WPF 和 F# 背后的代码

Code behind WPF and F#

是否可以在 F# 中制作一个使用 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) {
    }
}

这是标记

<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>

可能不会。据我所知 F# 不支持部分 类.

但您可以使用 F# XAML 类型提供程序,如下所述:http://www.mindscapehq.com/blog/index.php/2012/04/29/using-wpf-elements-from-f/

这真的取决于你所说的 "classic code behind" 是什么意思。正如 Petr 所提到的,F# 没有部分 classes(并且也没有编辑器支持),因此您不会获得相同的体验(当您访问元素或添加事件时)。但是您当然可以构建使用相同编程模型的 WPF 应用程序。

获得非常接近标准代码的方法之一是定义一个 class,与每个 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 类型的提供程序(但遗憾的是,文档不多)。

我找到了一个解决方案,我只是简而言之,这是代码:

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>

这不是实际问题的答案,它仅适用于我的用例。所以请随时回答:)