Saturday, 2 October 2010

Simple rules to remember binding business objects to UI in xaml in .Net 4.0

A post for those who are novice in xaml, binding and .Net 4.0

Remeber that
1. variables cannot be bind in xaml, only properties, so when we write in xaml something like
Text="{Binding MyVar, Mode=TwoWay}

we need to remember to write declaring the classs: instead of

Public MyVar as integer

the following

Public Property MyVar as integer


2. You will need to push a notification if you want UI to be updated updating the business object, so use OnPropertyChanged (link) and so writting the full notation (with Get and Set) instead of the short notation we seen above.

3. Don't forget that you either need to rebind lists, or use instead of simply collections like lists and dictionaries an observablecollection etc (link)

Slightly more advance
1. Don't foget that you can use converters binding a property to UI to represent, for example, a boolean value as a picture

<controls:ChildWindow.Resources >
        <loc:RO_FavImageTypeConverter  x:Key="FavConverter" />

<Image Source="{Binding Favorite, Converter={StaticResource FavConverter}}"/>

Public Class RO_FavImageTypeConverter
  Implements IValueConverter
  Public Function Convert(ByVal value As ObjectByVal targetType As TypeByVal parameter As ObjectByVal culture As Globalization.CultureInfoAs Object _
  Implements System.Windows.Data.IValueConverter.Convert
    If value Is Nothing Then Return Nothing
    Dim bIsFav = DirectCast(value, Boolean)
    If bIsFav Then
      Return Utility.ImageHelper.GetImageSource("Resources/favor_yellow.png")
      Return Utility.ImageHelper.GetImageSource("Resources/favor_grey.png")
    End If
  End Function

PS: you can easily find in net how to apply the converter in xaml. Besides Utility.ImageHelper.GetImageSource is just illustrative - you will need to write your own code

2. Notice that you can use converter parameters. For example:

Text="{Binding Amount, Mode=TwoWay, Converter={StaticResource nmbFormat}, ConverterParameter='n0'}"

but be aware that nature of them is quite static. I mean that you can pass (bind) a property to that, but unfortunately you cannot bind two properties in the effective two way interaction.

Consider for example a simple case: you have a class, which contains an amount and a format to be applied on the amount in UI. you can bind Amount as above, but then you bind the number format, as the parameter is static. OK, you can change it by using the valueconverter as in the item 1 above, to get the entire instance of the class into the convertion function to read both amount and the number format, but then you will lose the two way nature of binding: the convert back will get a number enter, for example, into a text box, but were after convertion it will go? into the entire class? obviously it will not work any longer since you have no reference to the instance to which the inputted property should be placed to. If two way need to be working bind a simple property to make it automatically routed to the right places within the binded instance to be updated following UI update.

No comments: