WPF之DataTemplate
DataTemplate顾名思义,就是数据模板,用来指定数据的表现形式。这对于ItemsControl类的控件尤其有用,可以改变列表项的外观,更具有表现能力。
例如
View Code
<Grid> <Grid.Resources> <src:Customers x:Key="customers"/> </Grid.Resources> <ListBox ItemsSource="{StaticResource customers}" Width="350" Margin="0,5,0,10"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Padding="5,0,5,0" Text="{Binding FirstName}" /> <TextBlock Text="{Binding LastName}" /> <TextBlock Text=", " /> <TextBlock Text="{Binding Address}" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid>
上例中通过指定ListBox.ItemTemplate属性来定义子项的显示格式,如果不是列表项,可以通过控件的ContentTemplate属性来指定应用哪个数据模板。
使用起来比较简单,大概分为三步:
1.如果有些属性不是可以直接使用,需要转换的,写转换器,实现IValueConverter接口
2.定义好转换器之后,需要实例化,指定给需要的绑定
3.定义模板,也就是需要的显示格式
4.应用模板,把定义好的模板指定到目标控件的ContentTemplate或者ItemTemplate
看一个完整的例子
1.用来封装的实体类和转换器
View Code
class Car
{
public string Automaker { get; set; }
public string Name { get; set; }
public string Year { get; set; }
public string TopSpeed { get; set; }
}
//厂商名称转化为Logo图片
public class AutomakerToLogoPathConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string uriStr = string.Format(@"images/{0}.jpg",value.ToString());
return new BitmapImage(new Uri(uriStr, UriKind.Relative));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
//汽车名称转化为图像
public class NameToPhotoPathConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string uriStr = string.Format(@"images/{0}.jpg", value.ToString());
return new BitmapImage(new Uri(uriStr, UriKind.Relative));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
2.模板及窗体
View Code
<Window x:Class="TempaletPractise.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TempaletPractise" Title="汽车展览" Height="350" Width="623"> <Window.Resources> <!--Converter--> <local:AutomakerToLogoPathConverter x:Key="a2l"></local:AutomakerToLogoPathConverter> <local:NameToPhotoPathConverter x:Key="n2p"></local:NameToPhotoPathConverter> <!--Data Template for Detail View--> <DataTemplate x:Key="carDetailViewTemplate"> <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6"> <StackPanel Margin="5"> <Image Width="400" Height="250" Source="{Binding Name, Converter={StaticResource n2p}}"></Image> <StackPanel Orientation="Horizontal" Margin="5,0"> <TextBlock Text="Name:" FontWeight="Bold" FontSize="20"></TextBlock> <TextBlock Text="{Binding Name}" FontSize="20" Margin="5,0"></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5,0"> <TextBlock Text="Automaker" FontWeight="Bold"></TextBlock> <TextBlock Text="{Binding Automaker}" Margin="5,0"></TextBlock> <TextBlock Text="Year" FontWeight="Bold"></TextBlock> <TextBlock Text="{Binding Year}" Margin="5,0"></TextBlock> <TextBlock Text="Top Speed" FontWeight="Bold"></TextBlock> <TextBlock Text="{Binding TopSpeed}" Margin="5,0"></TextBlock> </StackPanel> </StackPanel> </Border> </DataTemplate> <!--DataTemplate for Item View--> <DataTemplate x:Key="carListItemViewTemplate"> <Grid Margin="2"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Automaker,Converter={StaticResource a2l}}" Grid.RowSpan="3" Width="64" Height="64"></Image> <StackPanel Margin="5,0"> <TextBlock Text="{Binding Name}" FontSize="16" FontWeight="Bold"></TextBlock> <TextBlock Text="{Binding Year}" FontSize="14"></TextBlock> </StackPanel> </StackPanel> </Grid> </DataTemplate> </Window.Resources> <!--窗体的内容--> <StackPanel Orientation="Horizontal" Margin="5"> <UserControl ContentTemplate="{StaticResource carDetailViewTemplate}" Content="{Binding SelectedItem, ElementName=listBoxCars}"></UserControl> <ListBox x:Name="listBoxCars" Width="180" Margin="5,0" ItemTemplate="{StaticResource carListItemViewTemplate}"></ListBox> </StackPanel> </Window>
3.指定数据源
View Code
private void InitialCarList() { List<Car> cars = new List<Car>() { new Car(){ Automaker="CADILLAC",Name="CADILLAC1",Year="1990",TopSpeed="340"}, new Car(){ Automaker="Ferrari",Name="Ferrari1",Year="1991",TopSpeed="350"}, new Car(){ Automaker="LAMBORGHINI",Name="LAMBORGHINI1",Year="1992",TopSpeed="360"}, new Car(){ Automaker="PORSCHE",Name="PORSCHE1",Year="1993",TopSpeed="370"} }; this.listBoxCars.ItemsSource = cars; }
参考 MSDN 《深入浅出WPF》第11章
ps.今天看到园子编辑推荐的一则新闻,Silverlight开始边缘化,从官方就开始不推了,不知道WPF的命运会怎样,在微软的大船上,只能跟着起伏,不过今天能从ASP.NET转WPF,明天也能从WPF转其他技术,我们从来就不怕这个,毕竟我们学过,想过,用过,他帮助过我们,每种技术都代表了一种思想,技术可以没落,思想却沉淀下来了。