如何在F#中启用WinForms或WPF项目?

时间:2018-05-16 14:29:23

标签: visual-studio f#

我安装了最新版本的Visual Studio 2017。我选择了F#语言支持和F#桌面支持。重新启动并转到文件 - >新项目我期待看到为F#启动新的WPF或WinForms项目的选项,但我没有任何此类选项。只有控制台,库,ASP.NET核心和教程。

如何为F#桌面应用程序启用或查找新项目模板?

4 个答案:

答案 0 :(得分:21)

您可以在F#中创建WPF和WinForms应用程序。没有模板,但它肯定是可能的,许多人这样做。要创建一个简单的WinForms应用程序,您可以执行以下操作:

  • 创建一个新的控制台应用程序。转到项目属性并将“应用程序”页面中的“输出类型”从“控制台应用程序”更改为“Windows应用程序”

  • 右键单击项目中的“References”并添加对“System.Windows.Forms”和“System.Drawing”的引用(在“Framework”选项卡中)。

  • 使用以下内容替换Program.fs中的代码:

    open System.Windows.Forms
    
    let f = new Form()
    f.Controls.Add(new Label(Text="Hello world!"))
    Application.Run(f)
    

对于任何更大的东西,你可能想要使用一个漂亮的F#GUI库,例如Isaac或FsXaml提到的Gjallarhorn项目,但基本的第一步将是相同的 - 创建一个控制台项目,使其成为一个Windows项目,然后添加相关的GUI框架参考。

答案 1 :(得分:9)

据我所知,没有"开箱即用" F#上的WPF或WinForms模板,但(至少在VS2015中)有一组WPF应用程序的社区模板。说实话,你真的不需要模板,特别是如果你使用FSXaml项目,这样可以很容易地手工完成(https://github.com/fsprojects/FsXaml)。

答案 2 :(得分:9)

这不是一个简单的答案。这些项目没有内置项目模板,因为Windows窗体和WPF设计器都不了解F#。我们刚刚获得了F#的ASP.NET核心模板,所以我们不应该抱怨......很多。

另一方面,Winforms或WPF应用程序只是C#代码。您在设计器中执行的任何操作最终都是表单文件中的代码。 Winforms或WPF应用程序只是"只是"控制台应用程序,用于设置适当的环境并创建表单和控件。

使用XAML和WP实际上更容易,尤其是在使用MVVM或类似架构的情况下。这是因为您可以与F#代码分开开发XAML标记并将数据绑定到XAML。您甚至可以创建一个WPF类库项目,在没有任何代码的情况下创建Windows,页面和控件,然后在F#项目中使用它们。

有一些库使这更容易。一个选项是Elmish.WPF。您可以在单独的项目中创建XAML页面和窗口,然后在F#中创建模型等,将它们绑定在一起并启动主窗体。如果你查看repo的例子,大部分代码都将记录和命令定义为F#函数,例如:

type ClockMsg =
    | Tick of DateTime

type ClockModel =
    { Time: DateTime }

type Msg =
    | ClockMsg of ClockMsg
    | Increment
    | Decrement
    | SetStepSize of int

type Model = 
    { Count: int
      StepSize: int
      Clock: ClockModel }

let init() = { Count = 0; StepSize = 1; Clock = { Time = DateTime.Now }}

let clockUpdate (msg:ClockMsg) (model:ClockModel) =
    match msg with
    | Tick t -> { model with Time = t }

let update (msg:Msg) (model:Model) =
    match msg with
    | Increment -> { model with Count = model.Count + model.StepSize }
    | Decrement -> { model with Count = model.Count - model.StepSize }
    | SetStepSize n -> { model with StepSize = n }
    | ClockMsg m -> { model with Clock = clockUpdate m model.Clock }

将它们绑定在一起相对简单:

let view _ _ = 
    let clockViewBinding : ViewBindings<ClockModel,ClockMsg> =
        [ "Time" |> Binding.oneWay (fun m -> m.Time) ]

    [ "Increment" |> Binding.cmd (fun m -> Increment)
      "Decrement" |> Binding.cmdIf (fun m -> Decrement) (fun m -> m.StepSize = 1)
      "Count" |> Binding.oneWay (fun m -> m.Count)
      "StepSize" |> Binding.twoWay (fun m -> (double m.StepSize)) (fun v m -> v |> int |> SetStepSize)
      "Clock" |> Binding.vm (fun m -> m.Clock) clockViewBinding ClockMsg ]

运行整个应用程序

[<EntryPoint;STAThread>]
 let main argv = 
     Program.mkSimple init update view
     |> Program.withSubscription subscribe
     |> Program.runWindow (Elmish.CounterViews.MainWindow())

上面的代码来自Counter示例。 XAML视图在CounterViews项目中定义。您甚至可以删除.cs文件,项目编译就可以了。

答案 3 :(得分:2)

即将“很快”到你附近的IDE:

“您可以期待2019年我们发布的两个版本,.NET Core 3和.NET Framework 4.8。”

https://blogs.msdn.microsoft.com/dotnet/2018/05/07/net-core-3-and-support-for-windows-desktop-applications/