Monday, 6 April 2009

DataTemplateSelector

UPDATE: There is an alternate technique described here and example code available from GoogleCode.

On our till roll I want to display each different category of product using a specific DataTemplate.

We start by defining the DataTemplates to be used in the usual way:

<DataTemplate x:Key="listBookingTemplate">...
<DataTemplate x:Key="listCCardTemplate">...
<DataTemplate x:Key="listCashTemplate">...
<DataTemplate x:Key="listDefaultTemplate">...

Then the DataTemplateSelector which is the link between the xaml DataTemplates and the C# class (TillRollTemplateSelector) that determines which template to use:

<ss:TillRollTemplateSelector 
 BookingTemplate="{StaticResource listBookingTemplate}" 
 CCardTemplate="{StaticResource listCCardTemplate}"
 CashTemplate="{StaticResource listCashTemplate}"  
 DefaultTemplate="{StaticResource listDefaultTemplate}" 
 x:Key="tillTemplateSelector" />

Then we need to wire up the template selector resource (tillTemplateSelector) to the ListBox that will display the data:

<ListBox Name="theTillRoll" Height="250" Width="330"
 ItemsSource="{Binding Source={StaticResource ViewModel}, Path=SaleItems}" 
 ItemTemplateSelector="{StaticResource tillTemplateSelector}"
 />

Finally, we define the C# class:

public class TillRollTemplateSelector : DataTemplateSelector
{
public DataTemplate BookingTemplate { get; set; }
public DataTemplate CashTemplate { get; set; }
public DataTemplate CCardTemplate { get; set; }
public DataTemplate DefaultTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is BookingLineItem) return BookingTemplate;
if (item is CashPaymentLineItem) return CashTemplate;
if (item is CCardPaymentLineItem) return CCardTemplate;
return DefaultTemplate;
}
}

The object item passed to the SelectTemplate method is of the same type as bound to the ListBox via the ItemsSource.

No comments: