【问题标题】:Create button handler in F# for WinForms app在 F# 中为 WinForms 应用程序创建按钮处理程序
【发布时间】:2013-07-21 13:08:56
【问题描述】:

我正在尝试在 F# 中制作一个非常简单的应用程序。我只想用点击事件制作一个小按钮,它将调用MessageBox.Show() 方法。

open System
open System.Windows.Forms

module FSI =
    [<System.Runtime.InteropServices.DllImport("user32.dll")>]
    extern bool ShowWindow(nativeint hWnd, int flags)
    let HideConsole() = 
        let proc = System.Diagnostics.Process.GetCurrentProcess()
        ShowWindow(proc.MainWindowHandle, 0)

FSI.HideConsole()

let form1 = new Form()
form1.Text <- "App"

let Test() = ( MessageBox.Show("Clicked.") )

let button1 = new Button( Text = "Click Me" )
button1.Click.AddHandler(fun _ _ -> Test())

form1.Controls.Add(button1)    

[<STAThread>]
do
   Application.Run(form1)

错误发生在:

  • FSI.HideConsole() // 警告
  • button1.Click.AddHandler(fun _ _ -> Test()) // 编译错误

它们很相似。

对于第一个:

  • 警告此表达式应具有“unit”类型,但具有“bool”类型。使用 'ignore' 丢弃表达式的结果,或使用 'let' 将结果绑定到名称。

第二次:

  • 此表达式应为 unit 类型,但此处为 DialogResult 类型

【问题讨论】:

    标签: winforms events f# click messagebox


    【解决方案1】:

    F# 函数隐式返回其最后一个表达式的结果,因此目前您的函数 Test() 返回 MessageBox.Show(string) 的结果。要创建返回 void/unit 的函数,可以使用忽略运算符。

    let Test() = ignore (MessageBox.Show("Clicked."))
    

    必须做额外的括号包装有点麻烦,所以通常使用 pipeforward (|&gt;) 运算符,它不需要:-

    let Test() = MessageBox.Show("Clicked.") |> ignore
    

    这也可以应用于您对 HideConsole 的调用。编译器使用警告通知您未使用 HideConsole 的返回值。

    【讨论】:

    • 当我按照你所说的做时,我得到了新的错误:连续的参数应该用空格或元组分隔,涉及函数或方法应用程序的参数应该用括号括起来。
    • 刚刚编辑了我的答案。您必须将对 MessageBox.Show 的调用用括号括起来。
    • 谢谢!它现在可以工作,但是您在此处提供的第一个变体在 VS 中对我不起作用:(
    • @GeloVolro 查看编辑。 (顺便说一句,对我来说,第一个在 VS2012 中就是这样)
    • @RubenBartelink 我用过 VS2010,但我安装了最后一个 .NET FW。
    猜你喜欢
    • 2011-06-15
    • 2016-08-20
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多