WPF DataTemplate

WPF中引入模板(Template)将数据和算法的“内容”与“形式”解耦。WPF:中Template分为两大类:ControlTemplate和DataTemplate。
下面详细介绍DataTemplate:
DataTemplate是数据内容的表现形式,一条数据显示成什么样子,是简单的文本还是直观的图形动画就由他来决定。

DataTemplate常用的地方有3处,分别是:
1. ContentControl的ContentTemplate属性,相当于给ContentControl的内容穿衣服。
2. ItemsControl的ItemTemplate属性,相当于给ItemsControl的数据条目穿衣服。
3. GridViewColumn的CellTemplate属性,相当于给GridViewColumn单元格的数据穿衣服。

下面看一个例子:有一列汽车数据,在列数据显示在一个ListBox里,要求ListBox的条目显示汽车的厂商图标和简要参数,单击某个条目后在窗体的详细内容区域显示汽车的图片和详细参数。

厂商的Logo和汽车的图片先添加到项目里。
这里写图片描述

创建Car类:

public class Car
{
    public string Automaker { get; set; }
    public string Name { get; set; }
    public string Year { get; set; }
    public string TopSpeed { get; set; }
}

有些属性不能直接拿来用,比如汽车的厂商和名称不能直接拿来作为图片的路径,这时就要使用Converter。有两种办法可以在XAML代码中使用Converter:
1. 把Converter以资源的形式放在资源词典里。
2. 为Converter准备一个静态属性,形成单件模式,在XAML代码里使用{x:Static}标签扩展来访问。

我们的两个Converter代码如下:

//厂商名称转换为Logo图片路径
public class AutomakerToLogoPathConverter : IValueConverter
{
    //正向转换
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string uriStr = string.Format(@"/Resources/Logos/{0}.png", (string)value);
        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(@"/Resources/Images/{0}.jpg", (string)value);
        return new BitmapImage(new Uri(uriStr, UriKind.Relative));
    }

    //未被用到
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

窗体部分代码:

<Window.Resources>
    <!--Converters-->
    <localCon:AutomakerToLogoPathConverter x:Key="a2l" />
    <localCon:NameToPhotoPathConverter x:Key="n2p" />
    <!--DataTemplate 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}}" />
                <StackPanel Orientation="Horizontal" Margin="5,0">
                    <TextBlock Text="Nmae:" FontWeight="Bold" FontSize="20" />
                    <TextBlock Text="{Binding Name}" FontSize="20" Margin="5,0" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" Margin="5,0">
                    <TextBlock Text="Automaker:" FontWeight="Bold" />
                    <TextBlock Text="{Binding Automaker}" Margin="5,0" />
                    <TextBlock Text="Year:" FontWeight="Bold" />
                    <TextBlock Text="{Binding Year}" Margin="5,0" />
                    <TextBlock Text="Top Speed:" FontWeight="Bold" />
                    <TextBlock Text="{Binding TopSpeed}" Margin="5,0" />
                </StackPanel>
            </StackPanel>
        </Border>
    </DataTemplate>
    <!--DateTemplate 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" />
                <StackPanel Margin="5,10">
                    <TextBlock Text="{Binding Name}" FontSize="16" FontWeight="Bold" />
                    <TextBlock Text="{Binding Year}" FontSize="14" />
                </StackPanel>
            </StackPanel>
        </Grid>
    </DataTemplate>
</Window.Resources>

<!--窗体内容-->
<StackPanel Orientation="Horizontal" Margin="5">
    <UserControl ContentTemplate="{StaticResource carDetailViewTemplate}"
                    Content="{Binding SelectedItem, ElementName=listBoxCars}" />
    <ListBox x:Name="listBoxCars" Width="180" Margin="5,0"
                ItemTemplate="{StaticResource carListItemViewTemplate}" />
</StackPanel>

后台代码:

public MainWindow()
{
    InitializeComponent();
    InitialCarList();
}

private void InitialCarList()
{
    List<Car> carList = new List<Car>()
    {
        new Car(){ Automaker="Lamborghini", Name="Diablo", Year="1990", TopSpeed="340" },
        new Car(){ Automaker="Lamborghini", Name="a", Year="2001", TopSpeed="353" },
        new Car(){ Automaker="Lamborghini", Name="Gallardo", Year="2003", TopSpeed="325" },
        new Car(){ Automaker="Lamborghini", Name="Reventon", Year="2008", TopSpeed="356" },
    };

    this.listBoxCars.ItemsSource = carList;
}

效果如图:
这里写图片描述

DataTemplate实现了“数据驱动界面”,让Binding和数据关联参透到用户的每一个界面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值