WPF: Tips - Binding Text to Numeric Resource
Occasionally you want some value type like a string or number to be available application wide.
A variable as a resource is one obvious approach - as it turns out these can be tricksy rascals though.
A Value Type
The first thing to cover is how you actually get a value type in the first place.
These can be added to a Resource Dictionary which is merged in App.xaml.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
<sys:Double x:Key="MyNumber">42</sys:Double>
<sys:String x:Key="MyString">42</sys:String>
A reference is added to mscorlib which then allows us to use simple value types in XAML. There's a Double type with a value of 42 and a String type, again with a value 42.
Using That - Read Only
Using that string in markup would be:
<TextBlock Text="{StaticResource MyString}"/>
Which works, no problem. You already know if it was always that easy you wouldn't be reading this though.
Let's try that with the number then.
<TextBlock Text="{StaticResource MyNumber}"/>
That lights up with an error straight off:
An object of the type "System.Double" cannot be applied to a property that expects the type "System.String".
Oops !
Bindings automatically do conversion to string so maybe a Binding might get round this.
<TextBlock Text="{Binding Source={StaticResource MyNumber}}"/>
Ahah!
That runs.
Read Write
How about if we want to edit that though?
Let's try a TextBox.
<TextBox Text="{Binding Source={StaticResource MyNumber}}"/>
Oh dear.
That lights up with an error:
Two-way binding requires Path or XPath.
Let's stick a path on the end then.
The source is the actual object so how about a dot notation for the same thing?
<TextBox Text="{Binding Source={StaticResource MyNumber}, Path=.}"/>
That appears to work.
Then we find that variable can change.
A quick experiment with a button:
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Application.Current.Resources["MyNumber"] = (double)66;
}
And that number doesn't change in the view - it's a StaticResource.
Well then maybe make it a DynamicResource instead then.
That gives a run time error:
A 'DynamicResourceExtension' cannot be set on the 'Source' property of type 'Binding'. A 'DynamicResourceExtension' can only be set on a DependencyProperty of a DependencyObject.
We need that path there, as we saw earlier.
How about setting the DataContext on the TextBox?
<TextBox DataContext="{DynamicResource MyNumber}" Text="{Binding Path=.}" />
Which works.
You can edit that and it changes MyNumber.
Click the button and it changes to 66 in the TextBox.
See Also
This article is part of the WPF Tips Series, if WPF is your area of interest then you will probably find other useful articles there.