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/