WPF和F#的代码后台

3

是否可以在F#中创建一个使用经典的代码后台(即有code behind)的WPF应用程序?我知道它与MVVM和无代码后台非常配合,但我需要在UserControl上实现一个接口。在F#中是否可能?

为了帮助一下,这里是我想要从C#翻译成F#的代码:

public class Test : UserControl, IContent {

    public void InitializeComponents() {
        // Do the initialization magic
    }

    public Test() {
    }

    public void OnFragmentNavigation(FragmentNavigationEventArgs e) {
        this.DataContext = new { description = "Hallo Welt :)" };
    }

    public void OnNavigatedFrom(NavigationEventArgs e) {
    }

    public void OnNavigatedTo(NavigationEventArgs e){
    }

    public void OnNavigatingFrom(NavigatingCancelEventArgs e) {
    }
}

这是标记

,与此相关的是it技术。

<UserControl xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="Test">
    <TextBlock Text="{Binding description}"></TextBlock>
</UserControl>

试试这个... https://github.com/fsprojects/FsXaml - Ayyappan Subramanian
在WPF的UserControls中,你不需要“实现接口”。为什么要这样做呢? - Federico Berasategui
@HighCore 请查看此处:https://github.com/firstfloorsoftware/mui/wiki/Handle-navigation-events - Knerd
在我看来,应用程序的“导航”功能是应用程序本身的责任,而不是用户界面的责任。在WPF中,ViewModels是“应用程序”,而不是Views,因此该代码不属于UI,因此您不需要在UI中使用任何接口。 - Federico Berasategui
@HighCore,是的,我有。框架处理UserControl上的导航事件。我已经提出了一个问题,是否可以在ViewModel中完成它 ;) - Knerd
3个回答

4

这实际上取决于您所谓的 "经典代码后台" 是什么意思。正如Petr所提到的,F#没有部分类(也没有编辑器支持),因此您将无法获得相同的体验(当您访问元素或添加事件时)。但是您肯定可以构建一个使用相同编程模型的WPF应用程序。

获得非常接近标准代码后台的一种方法是定义一个类,与每个xaml文件关联,看起来像这样:

type SomeComponent() =
  let uri = System.Uri("/AppName;component/SomeComponent.xaml", UriKind.Relative)
  let ctl = Application.LoadComponent(uri) :?> UserControl

  let (?) (this : Control) (prop : string) : 'T =
    this.FindName(prop) :?> 'T

  let okBtn : Button  = ctl?OkButton
  do okBtn.Click.Add(fun _ -> (* .. whatever *) )

这会加载XAML内容,然后使用动态查找运算符来查找所有UI元素(在C#中您将获得免费的功能)。更好的F#解决方案是使用FsXaml,它具有XAML类型提供程序(但遗憾的是,文档不多)。


检查我的编辑,代码本身很棒 :) 可能会对我另一个问题有所帮助 ^^ - Knerd

2
我找到了一个解决方案,我简单地说明一下,这里是代码:

namespace Testns

open System.Windows.Controls
open FirstFloor.ModernUI.Windows
open Microsoft.FSharp.Core
open System

type TestUserControl() =
    inherit UserControl()

    interface IContent with
        member x.OnFragmentNavigation(e: Navigation.FragmentNavigationEventArgs): unit = 
            let vm = ViewModel("Hallo Welt :)")
            base.DataContext <- vm
            ()

        member x.OnNavigatedFrom(e: Navigation.NavigationEventArgs): unit = ()

        member x.OnNavigatedTo(e: Navigation.NavigationEventArgs): unit = ()

        member x.OnNavigatingFrom(e: Navigation.NavigatingCancelEventArgs): unit = ()

并且标记

<local:TestUserControl xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Testns;assembly=App">
    <TextBlock Text="{Binding description}"></TextBlock>
</local:TestUserControl>

这不是实际问题的答案,只适用于我的使用情况。所以请随意回答它 :)

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接