Friday, March 6, 2009

WPF Data Binding - DataTemplates

Creating a DataTemplate enables you to specify a different visual structure of UI elements when displaying your data object. When the binding mechanism is asked to display a data object, it will use the UI elements specified in the DataTemplate to render it.
The following example demonstrates a window that contains a System.Windows.Controls.
ListBox
control. The ItemsSource property of the ListBox is bound to a collection of DiskDrive
objects. The DiskDrive class exposes Type, Capacity and Image properties. The ItemTemplate property of the ListBox is set to a static resource called mainTemplate. This is a DataTemplate resource defined in the window’s System.Windows.ResourceDictionary. The DataTemplate creates a System.Windows.Controls.Grid control inside a System.Windows.Controls.Border control. Inside the Grid, it defines a series of System. Windows.Controls.TextBlock controls and a System.Windows.Controls.Image control. These controls have standard binding statements that bind their properties to properties on the DiskDrive class. When the window opens and the ListBox binds to the collection of DiskDrive objects, the binding mechanism uses the set of UI elements in the DataTemplate to display each item.

XAML for the example is as

<Window.Resources>
<local:ImagePathConverter x:Key="ImagePathConverter" />
<Style TargetType="{x:Type TextBlock}" x:Key="normalTextStyle"> <Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="2" />
<Setter Property="Foreground" Value="Blue" />
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="displayTextStyle" BasedOn="{StaticResource normalTextStyle}">
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="Foreground" Value="Black" />
</Style>
<DataTemplate x:Key="mainTemplate">
<Border BorderBrush="Red" Background="White" BorderThickness="1" Padding="4" Margin="4" Height="Auto" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="Drive Type" Style="{StaticResource normalTextStyle}" />
<TextBlock Text="{Binding Path=Type}" Style="{StaticResource displayTextStyle}" />
<TextBlock Text="Capacity" Style="{StaticResource normalTextStyle}" />
<TextBlock Text="{Binding Path=Capacity}" Style="{StaticResource displayTextStyle}" />
</StackPanel>
<Image Grid.Column="1" Width="100" Height="100" Source="{Binding Converter={StaticResource ImagePathConverter}, Path=Image}" />
</Grid>
</Border>
</DataTemplate>
</Window.Resources>


You can set the ItemTemplate of the ListBox as

<ListBox ItemTemplate="{StaticResource mainTemplate}" Margin="10" Name="diskDriveList" />


In the code behind file you set the ItemSource property of the ListBox as

this.diskDriveList.ItemsSource = new List
{
new DiskDrive { Type = "CD", Capacity = "700 MB", Image=@"D:\Prajeesh\Images\DiskDrives\CD.png" },
new DiskDrive { Type = "DVD", Capacity = "4.1 GB", Image=@"D:\Prajeesh\Images\DiskDrives\DVD.png" },
new DiskDrive { Type = "HD", Capacity = "360 GB", Image=@"D:\Prajeesh\Images\DiskDrives\HD.png" },
new DiskDrive { Type = "HD-Network", Capacity = "40 GB", Image=@"D:\Prajeesh\Images\DiskDrives\HD-Network.png" },
new DiskDrive { Type = "HD-Win", Capacity = "160 GB", Image=@"D:\Prajeesh\Images\DiskDrives\HD-Win.png" }};


The DiskDrive class
public class DiskDrive
{
public string Type { get; set; }
public string Image { get; set; }
public string Capacity { get; set; }
}

Output

No comments: