I am busy creating a nTier WPF app that rely very heavy on binding... here are some of the less obvious things I have learned about data binding in WPF
1) Binding path "(TextBox.Text)" vs "Text"?
If you bind to a path called Text, WPF uses reflection to resolve the name. If you use the class-qualified name, binding avoids the reflection performance hit. Class-qualified names also allows binding to attached properties!
2) WPF doesn't raise exceptions to notify you about data binding problems
All binding errors are output as trace information and NOT exceptions!
Beatriz Costa (Who else) has a excellent article about this
3) Why use OneWayToSource binding mode?
Well, the target object must always be a DP! The most common use of OneWayToSource mode is to by-pass this restriction! The source doesn't need to be a DP and effectively using OneWayToSource reverses the binding direction.
A perfect example is Run, it's text property is not backed by a DP!
4) Default binding mode?
Not all DP's have the same default binding mode!!!
If the binding mode is two-way, but the CLR property that it is bound to is read-only... will cause problems! just keep in mind that you can't assume what the binding mode is!!!
It is always a good idea to explicitly specify your binding mode. Also remember that OneWay is slightly lighter than TwoWay!
5) RelativeSourceMode.PreviousData
If you bind to a collection of prices and need to show the change from the previous price to the current price then this little trick can be very useful... Pass the current item and the following binding into a IMultiValueConverter converter
{Binding RelativeSource={RelativeSource PreviousData}} |
The multi value converter now just need to work out what the difference is!
6) RelativeSourceMode.FindAncestor
This is a very cool hack I found... Lets assume that you have a ListBox showing data. Normally if you have a TextBlock inside your DataTemplate and you don't supply it with a foreground color, then it would inherit the parents Foreground property. What is cool about this is that then when you click on the item, the font color would change from black to white! Now assume that your DataTemplate also contains a custom control that do not rely on the Foreground property to determine its color (As a example, I will use a Ellipse which has a Fill and not a Foreground/Background). If I add a Ellipse to this DataTemplate and I do not set its fill, it would stay blank. Even if I give it a Fill color, it will fill with this color but if I now select this ListBox item, it will stay the provided color!
So how do I make my ellipse inherit the Foreground color and more importantly, how do I make it change to white once selected? Binding its Fill with the following
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=Foreground} |
Now, it will inherit the parents Foreground and also change once selected...
7) Binding a ListBox to a custom object, What gets displayed in the ListBox?
When binding to a custom object, determining what is displayed in the ListBox can be one of 3 options
8) {Binding Path=/}
Bind to the current item in the view! Just remember to set IsSynchronizedWithCurrentItem to true
[UPDATE] While reading Ian Griffiths blog, I found a entry detailing this behaviour in WPF databinding
9) Binding has a constructor that take Path as a parameter
This is just a small shortcut
{Binding Path=Name} |
Can be written like this
{Binding Name} |
10) {Binding}
This looks a little weird but all this means is that the source is defined somewhere up the tree... common place is Window.DataContext. By setting the DataContext to a collection, I can now add a ListBox to the visual tree and then binding this ListBox's ItemsSource to {Binding}. This will tell the ListBox that its ItemsSource is the DataContext of the Window!