【问题标题】:Code behind WPF and F#WPF 和 F# 背后的代码
【发布时间】:2015-05-16 12:09:55
【问题描述】:

是否可以在 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>

【问题讨论】:

  • 您不会在 WPF 的 UserControls 中“实现接口”。你为什么要这么做?
  • @Knerd 恕我直言,应用程序“导航”功能是应用程序本身的责任,而不是 UI。在 WPF 中,ViewModel 是“应用程序”,而不是视图,因此该代码不属于 UI,因此您不需要 UI 中的任何接口。
  • @HighCore,是的,我愿意。框架处理UserControl 上的导航事件。如果可以在 ViewModel 中执行,我已经打开了一个问题;)

标签: wpf f# c#-to-f#


【解决方案1】:

我找到了解决办法,我就简单说一下,代码如下:

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>

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

【讨论】:

    【解决方案2】:

    这真的取决于你所说的“经典代码背后”是什么意思。正如 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 类型提供程序(但遗憾的是,没有太多文档)。

    【讨论】:

    • 检查我的编辑,它自己的代码很棒:) 可能有助于解决我遇到的另一个问题^^
    【解决方案3】:

    可能没有。据我所知,F# 不支持部分类。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 2011-02-02
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      相关资源
      最近更新 更多