wpf - F# 如何以编程方式在 WPF 标签上设置内容

标签 wpf f#

F# 代码

open System
open System.Windows
open System.Windows.Controls

let resourceLocator = new Uri("/ConsoleApplication3;component/MainWindow.xaml", UriKind.Relative)

let lbl2 = (Application.LoadComponent(resourceLocator) :?> Window).FindName("lbl") :?> Label

let tb = (Application.LoadComponent(resourceLocator) :?> Window).FindName("tb") :?> TextBlock

let tbo = (Application.LoadComponent(resourceLocator) :?> Window).FindName("tbo") :?> TextBox

let value = "ROCK!"
let clickButton = fun _ -> 
    lbl2.Content <- "ROCK!"

let loadWindow() = 
    let resourceLocator = new Uri("/ConsoleApplication3;component/MainWindow.xaml", UriKind.Relative)
    let window = Application.LoadComponent(resourceLocator) :?> Window
    (window.FindName("clickButton") :?> Button).Click.Add(clickButton)
    window

[<STAThread>]
(new Application()).Run(loadWindow()) |> ignore

我的 Xaml WPF 代码:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="500">
    <Grid>
        <Button Name="clickButton" Content="Click  me!" Height="40" Width="150" />
        <Label Name="lbl" Content="Label" HorizontalAlignment="Left" Margin="198,40,0,0" VerticalAlignment="Top"/>
        <TextBlock Name="tb" HorizontalAlignment="Left" Margin="198,201,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
        <TextBox Name="tbo" HorizontalAlignment="Left" Height="23" Margin="340,198,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
    </Grid>
</Window>

我打算通过单击按钮来更改 Label:lbl 的内容,但由于某种原因它不起作用,但不明白为什么

最佳答案

在这种情况下,问题在于您多次加载该组件。当您调用 clickButton 时,它使用绑定(bind)值的结果,该绑定(bind)值绑定(bind)到与主实例分开的已加载窗口实例。

在本例中,您应该能够通过使用 Application.Current.MainWindow 获取已显示的窗口来解决此问题:

open System
open System.Windows
open System.Windows.Controls

let resourceLocator = new Uri("/ConsoleApplication3;component/MainWindow.xaml", UriKind.Relative)

// This needs to be a function, so it's not evaluated before the window is created
let getLbl2 () = Application.Current.MainWindow.FindName("lbl") :?> Label

let value = "ROCK!"
let clickButton = fun _ -> 
    let lbl = getLbl2()
    lbl.Content <- "ROCK!"

let loadWindow() = 
    let resourceLocator = new Uri("/ConsoleApplication3;component/MainWindow.xaml", UriKind.Relative)
    let window = Application.LoadComponent(resourceLocator) :?> Window
    (window.FindName("clickButton") :?> Button).Click.Add(clickButton)
    window

[<STAThread>]
(new Application()).Run(loadWindow()) |> ignore

话虽这么说,我真的建议使用 FsXaml使用您的 WPF 资源。类型提供程序将为您提供对数据的类型安全访问,并使生活变得更加简单。

可以使用 FsXaml 将其重写为:

open System
open System.Windows
open System.Windows.Controls
open FsXaml

type MainWindow = XAML<"MainWindow.xaml">

let loadWindow() = 
    let window = MainWindow().CreateRoot()
    let accessor = MainWindow.Accessor window
    accessor.clickButton.Click.Add(fun _ -> accessor.lbl.Content <- "ROCK!")
    window

[<STAThread>]
(new Application()).Run(loadWindow()) |> ignore

请注意,使用 FsXaml 时,您可以获得成员的完整智能感知,并且不再需要魔术字符串。

关于wpf - F# 如何以编程方式在 WPF 标签上设置内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24942931/

相关文章:

c# - 每次按下按钮时都会创建一个新标签

f# - 使用元组对抽象类型进行类型推断

wpf - 自定义控件边框画笔属性不一致?

wpf - 为用户控件设置样式

c# - 将 DataTable 转换为 ObservableCollection(没有特定类)

F# JSON Typeprovider 因丢失数据而崩溃

.net - 在此 bind() 参数中省略 unit 参数时,我是否应该看到不同之处?

F# 将字符串传递给列表

f# - 在 F# 中将 System.Func<> 转换为 FastFunc<>

c# - WPF:StackPanel 与 FirstChildFill?