|
|
|
|
Data Templates
Introduction
Data Template are a similar concept as Control Templates. They give you a very flexible and powerful solution to replace the visual appearance of a data item in a control like ListBox, ComboBox or ListView. In my opinion this is one of the key success factory of WPF.
If you don't specify a data template, WPF takes the default template that is just a TextBlock. If you bind complex objects to the control, it just calls ToString() on it. Within a DataTemplate, the DataContext is set the data object. So you can easily bind against the data context to display various members of your data object
DataTemplates in Action: Building a simple PropertyGrid
Whereas it was really hard to display complex data in a ListBox with WinForms, its super easy with WPF. The following example shows a ListBox with a list of DependencyPropertyInfo instances bound to it. Without a DataTemplate you just see the result of calling ToString() on the object. With the data template we see the name of the property and a TextBox that even allows us to edit the value.
<!-- Without DataTemplate -->
<ListBox ItemsSource="{Binding}" />
<!-- With DataTemplate -->
<ListBox ItemsSource="{Binding}" BorderBrush="Transparent"
Grid.IsSharedSizeScope="True"
HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBox Grid.Column="1" Text="{Binding Value }" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How to use a DataTemplateSelector to switch the Template depending on the data
Our property grid looks nice so far, but it would be much more usable if we could switch the editor depending on the type of the property.
The simplest way to do this is to use a DataTemplateSelector. The DataTemplateSelector has a single method to override: SelectTemplate(object item, DependencyObject container). In this method we decide on the provided item which DataTemplate to choose.
The following exmple shows an DataTemplateSelector that decides between tree data templates:
public class PropertyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultnDataTemplate { get; set; }
public DataTemplate BooleanDataTemplate { get; set; }
public DataTemplate EnumDataTemplate { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
DependencyPropertyInfo dpi = item as DependencyPropertyInfo;
if (dpi.PropertyType == typeof(bool))
{
return BooleanDataTemplate;
}
if (dpi.PropertyType.IsEnum)
{
return EnumDataTemplate;
}
return DefaultnDataTemplate;
}
}
<Window x:Class="DataTemplates.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:DataTemplates"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Window.Resources>
<!-- Default DataTemplate -->
<DataTemplate x:Key="DefaultDataTemplate">
...
</DataTemplate>
<!-- DataTemplate for Booleans -->
<DataTemplate x:Key="BooleanDataTemplate">
...
</DataTemplate>
<!-- DataTemplate for Enums -->
<DataTemplate x:Key="EnumDataTemplate">
...
</DataTemplate>
<!-- DataTemplate Selector -->
<l:PropertyDataTemplateSelector x:Key="templateSelector"
DefaultnDataTemplate="{StaticResource DefaultDataTemplate}"
BooleanDataTemplate="{StaticResource BooleanDataTemplate}"
EnumDataTemplate="{StaticResource EnumDataTemplate}"/>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding}" Grid.IsSharedSizeScope="True"
HorizontalContentAlignment="Stretch"
ItemTemplateSelector="{StaticResource templateSelector}"/>
</Grid>
</Window>
How to react to IsSelected in the DataTemplate
If you want to change the appearance of a ListBoxItem when it is selected, you have to bind the IsSelected property of the ListBoxItem. But this is a bit tricky, you have to use a relative source with FindAcestor to navigate up the visual tree until you reach the ListBoxItem.
<DataTemplate x:Key="DefaultDataTemplate">
<Border x:Name="border" Height="50">
...
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource=
{RelativeSource Mode=FindAncestor, AncestorType=
{x:Type ListBoxItem}},Path=IsSelected}" Value="True">
<Setter TargetName="border" Property="Height" Value="100"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Comments on this article
Show all comments
 |
| OgiBoho | |
|
| Commented on 12.August 2009 |
| This is truly awesome article. It helped me a lot and it gave me good ideas.
|
|
|
 |
| dawmail333 | |
|
| Commented on 2.November 2009 |
| THANK YOU! I'd been searching to try and work out how to use IsSelected with a custom source for a while now. Thank you again!
|
|
|
 |
| chandrapal | |
|
| Commented on 5.November 2009 |
| This is a good article. I made same like this.using this article
|
|
|
 |
| Eric | |
|
| Commented on 18.November 2009 |
Hi,
I'm really stuck here with my listbox datatemplate:
I have a listbox where its datatemplate is a custom control
The lsitbox is bind to a datatable.
The datatable contains a integer GenderID (integer)
The customcontrol contains several textboxes and a combobox (gender)
All controls in the customcontrols are xaml binded and wotk perfectly, except for the combobox.
The problem is that the IstemsSource for the combobox is loaded after the control is initialized in the codebehind, meaning that the selectedvalue binding in xaml doesn't work.
The ItemsSource of the combobox is a datatable with 2 fields (ID (integer) & Gender(string)).
My Code:
'Fill the datatable
Dim oTBL As DataTable = GetGenderTBL()
Dim oBind As New Binding
With oCOMBO
.DataContext = oTBL
.DisplayMemberPath = "Gender"
.SelectedValuePath = "ID"
.SetBinding(ItemsControl.ItemsSourceProperty, oBind)
End With
Combo xaml:
<ComboBox Name="LstGender" Grid.Row="0" Grid.Column="7"
SelectedValue="{Binding Path=GenderID}"></ComboBox>
When running, the combobox list contains the items from the gender table, but no item is selected, the binding with Listbox GenderID doesn't work.
How can I load the combo ItemsSource before the controls in the listbox item are binding ?
Rgds,
Eric
|
|
|
 |
| yjmyzz | |
|
| Commented on 7.December 2009 |
| awesome !
|
|
|
 |
| Shankar | |
|
| Commented on 9.December 2009 |
| Nice to read...... ThankQ.
|
|
|
 |
| Meenatchi | |
|
| Commented on 10.December 2009 |
| Seems a nice article.It would be Great,if more explanation is given,especially for the beginners.
|
|
|
 |
| Stephen | |
|
| Commented on 15.December 2009 |
| I think I just decided to learn WPF...
|
|
|
 |
| sathya | |
|
| Commented on 11.February 2010 |
Hi Christian,
Thank you very much, i got very good basics of WPF, it is really helpfull, i really appreciate your work.Thank you, could you give me guideline how to study WCF bascis, you can send to my mail id sathyajan1@gmail.com. thank you again, i appreciate your work.
|
|
|
 |
| Yadav | |
|
| Commented on 11.March 2010 |
| Very helpful article and I would further appreciate if you give the UI prinout before and after the application of the template. Thank you.
|
|
|
 |
| ward | |
|
| Commented on 20.April 2010 |
| how can i use TreeView control to show SQL-database data in hierarchical view using c sharp.. please help me here because am working on windows from application project . iit's my graduation project.
|
|
|
 |
| Confused | |
|
| Commented on 21.June 2010 |
| This is a poor example. Where is the code behind? Where is the binding? What is this magic data you are adding to the list view?
|
|
|
 |
| Confused | |
|
| Commented on 22.June 2010 |
| This is a poor example. Where is the code behind? Where is the binding? What is this magic data you are adding to the list view?
|
|
|
 |
| Confused | |
|
| Commented on 22.June 2010 |
| This is a poor example. Where is the code behind? Where is the binding? What is this magic data you are adding to the list view?
|
|
|
 |
| tim | |
|
| Commented on 28.June 2010 |
| WOW
|
|
|
 |
| danielwu | |
|
| Commented on 23.July 2010 |
Mr Confused,
Before you make conclusion, you'd better finish the whole article and then you will find sample solution for download in the end...
|
|
|
 |
| Shankarnag | |
|
| Commented on 24.August 2010 |
| Its really very good information about data templates.
|
|
|
|
|