F# Code
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
My Xaml WPF Code:
<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>
I intend to change the content of a Label:lbl with a button click, but for some reason it is not working, but can't see why
The problem, in this case, is that you're loading the component more than once. When you call clickButton, it's using the result of a bound value that was bound to a loaded window instance separate from the main instance.
You should be able to work around this, in this case, by using Application.Current.MainWindow to get the window that's already been displayed:
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
That being said, I'd really recommend using FsXaml to work with your WPF resources. The type provider will provide you type safe access to your data, and make life far simpler.
This could be rewritten using FsXaml as:
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
Note that when using FsXaml, you get full intellisense of your members, and you don't need the magic strings anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With