深入浅出WPF-11.Template(模板)02

模板

DataTemplate和ControlTemplate的关系

通过上面的内容,控件只是一个数据和行为的载体,是一个抽象的概念,至于它长什么样子,或者它的数据是怎么展示的,都是由模板生成的。决定控件外观的ControlTemplate,决定数据外观的是DataTemplate,他们正式Control类的Template和ContentTemplate两个属性的值。

凡是Template最终都要作用在控件上,这个控件就是Template的目标控件,也叫模板化控件。DataTemplate给人的感觉是施加在数据对象上,但是施加在数据对象上生成的一组控件总要有一个载体,这个载体就是ContentPresenter对象。ContentPresenter对象只有ContentTemplate属性,没有Template属性,这就证明了承载由DataTemplate生成的一组控件的专门用途。

由ControlTemplate生成的控件树其树根就是ControlTemplate的目标控件,此模板化控件的Template属性值就是这个ControlTemplate实例;与之相仿,有DataTemplate生成的控件树其树根是一个ContentPresenter控件,此模板化控件的ContentTemplate属性值就是这个DataTemplate实例。因为ContentPresenter控件是ControlTemplate控件树上的一个结点,所以DataTemplate控件树是ControlTemplate控件树的一颗子树。

DataTemplate和ControlTemplate的绑定

每个控件都有一个名为TemplatedParent的属性,如果他的值不为null,说明这个控件是由Template自动生成的,而属性值就是应用了模板的控件。如果由Template生成的控件使用了TemplateBinding获取属性值,则TemplateBinding的数据源就是应用了这个模板的目标控件。

如果使用了普通绑定Binding而不是TemplateBinding,那么数据源就是Source,如果不指定的话,Binding就会沿着逻辑树一直向上找,查找每个结点的DataContext属性,如果DataContext引用的对象具有Path指定的属性名,Binding就会把这个对象当做自己的数据源。显然,如果把数据对象赋值给ContentPresenter的DataContext属性,有DataTemplate生成的控件自然会找这个数据对象作为自己的数据源。

简单的理解为:控件模板ControlTemplate中的改变的是控件的外形,使用的一般是TemplateBinding,对应的数据源是应用这个这个ControlTemplate的目标控件。DataTemplate数据模板改变的是数据的展示形式,一般是普通的Binding,数据源是需要展示的数据内容。

<DataTemplate x:Key="ListBoxItemOCTDataTemplate" DataType="{x:Type ListBoxItem}">
        <Border Margin="0">
            <Grid Width="{StaticResource ListBoxOCTWidth}" Height="{StaticResource ListBoxOCTHeight}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="5" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1">
                    <TextBlock
                        Margin="8,0,0,0"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Center"
                        FontSize="14"
                        Foreground="{StaticResource CommonForeground}"
                        ScrollViewer.VerticalScrollBarVisibility="Disabled"
                        SnapsToDevicePixels="True"
                        Text="{Binding ImageLaterality, Converter={StaticResource ListBoxEyeStringConverter}}"
                        TextWrapping="NoWrap" />
                    <TextBlock
                        Margin="0,0,8,0"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"
                        FontSize="14"
                        Foreground="{StaticResource CommonForeground}"
                        ScrollViewer.VerticalScrollBarVisibility="Disabled"
                        SnapsToDevicePixels="True"
                        Text="{Binding CreationDateTime}"
                        TextWrapping="NoWrap" />
                </Grid>
                <Grid Margin="2,2,2,2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="4" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.Column="0" Source="{Binding ImageJpgThumbPathBitmap}" />
                    <Image Grid.Column="2" Source="{Binding OCTJpgThumbPathBitmap}" />
                </Grid>
                <Grid Margin="2,2,2,2">
                    <Image Source="{Binding VideoFileFullPathBitmap}" />
                </Grid>
                <Grid Grid.Row="2">
                    <TextBlock
                        Margin="8,0,0,0"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Center"
                        FontSize="14"
                        Foreground="{StaticResource CommonForeground}"
                        ScrollViewer.VerticalScrollBarVisibility="Disabled"
                        SnapsToDevicePixels="True"
                        Text="{Binding ScanDataTypeRemark}"
                        TextWrapping="NoWrap" />
                </Grid>
            </Grid>
        </Border>
    </DataTemplate>

这里,切记一点控件的Template属性和ContentTemplate属性是两个完全不一样的,Template属性的值是ControlTemplate,而ContentTemplate的值是DataTemplate。

原文地址:https://www.cnblogs.com/vigorous/p/13408595.html