WPF控件模板

利用Tag来绑定控件模板内容

<!--模板定义-->
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" >
<UniformGrid Rows="2" Columns="1">
<TextBlock Text="{TemplateBinding Tag}" Background="Orange"/>
<ContentPresenter x:Name="contentPresenter"/>
</UniformGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--使用-->
<Button Style="{DynamicResource ButtonStyle1}" Height="60" Width="100" Tag="内部text">
ddd
</Button>

WPF控件模板、数据模板、容器样式选择器_.net

ItemsControl是基类,ListBox等都是继承自ItemsControl。ItemsControl里面有一个DataTemplate属性,可以定义数据模板

DataTemplate

<Window x:Class="WpfApp13.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp13"
mc:Ignorable="d"
Title="MainWindow" Height="250" Width="400">
<Window.Resources>
<x:Array x:Key="datas" Type="local:Person">
<local:Person Name="Tom1" Age="10" Top="10" Left="10"/>
<local:Person Name="Tom2" Age="10" Top="30" Left="20"/>
<local:Person Name="Tom3" Age="10" Top="50" Left="30"/>
<local:Person Name="Tom4" Age="10" Top="70" Left="40"/>
<local:Person Name="Tom5" Age="10" Top="90" Left="50"/>
<local:Person Name="Tom5" Age="10" Top="110" Left="60"/>
<local:Person Name="Tom5" Age="10" Top="130" Left="70"/>
</x:Array>
</Window.Resources>

<StackPanel>
<ListView ItemsSource="{StaticResource datas}" Height="218">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
<!--下面的ItemTemplate在这个容器中展示,默认是stackPanel-->
<!--但是并在不是直接在这个容器中展示,而是中间还有一层ContentPresenter-->
</ItemsPanelTemplate>
</ListView.ItemsPanel>

<!--Canvas.Left等属性必须在这里设定而不能在下面的ItemTemplate-->
<!--原因就是因为中间Canvas和ItemTemplate中间还有一层ContentPresenter-->
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Canvas.Left" Value="{Binding Left}"/>
<Setter Property="Canvas.Top" Value="{Binding Top}"/>

</Style>
</ListView.ItemContainerStyle>

<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Grid.Column="0"/>
<TextBlock Text="===" Grid.Column="1"/>
<TextBlock Text="{Binding Age}" Grid.Column="2" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Window>

WPF控件模板、数据模板、容器样式选择器_c#_02

筛选数据

使用DataTrigger筛选数据

<Window x:Class="WpfApp12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp12"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="400">
<Window.Resources>
<x:Array Type="local:Person" x:Key="datas">
<local:Person Name="Hello" Age="20" Gender="1"/>
<local:Person Name="Zhaoxi" Age="21" Gender="2"/>
<local:Person Name="Jovan" Age="22" Gender="1"/>
<local:Person Name="Jovan" Age="22" Gender="1"/>
<local:Person Name="Jovan" Age="18" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
</x:Array>
</Window.Resources>
<Grid>
<ListView ItemsSource="{StaticResource datas}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>

<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<!--在Style里面设置筛选-->
<!--使用DataTrigger筛选-->
<DataTrigger Binding="{Binding Age}" Value="20">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>

<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}" />
<TextBlock Text="{Binding Gender}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>

WPF控件模板、数据模板、容器样式选择器_xml_03

数据模板选择器

但是使用DataTrigger功能比较少,如果要选择某个区间的数据,可以使用模板选择器

新建​​ListViewItemTemplateSelector​​​类,该类继承自​​DataTemplateSelector​

class ListViewItemTemplateSelector : DataTemplateSelector
{
public DataTemplate NormalTemplate { get; set; }
public DataTemplate AlarmTemplate { get; set; }

/// <summary>
///
/// </summary>
/// <param name="item">每个控件子项所对应的数据子项</param>
/// <param name="container"></param>
/// <returns>当前的这个子项可使用的数据模板</returns>
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var person = item as Person;
if (person.Age > 21)
{
return AlarmTemplate;
}
return NormalTemplate;
}
}

xml

<Window x:Class="WpfApp12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp12"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="400">
<Window.Resources>
<x:Array Type="local:Person" x:Key="datas">
<local:Person Name="Hello" Age="20" Gender="1"/>
<local:Person Name="Zhaoxi" Age="21" Gender="2"/>
<local:Person Name="Jovan" Age="22" Gender="1"/>
<local:Person Name="Jovan" Age="22" Gender="1"/>
<local:Person Name="Jovan" Age="18" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
</x:Array>

<!--设置两个DataTemplae供选择器选择-->
<DataTemplate x:Key="NormalTemp">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Background="Yellow"/>
<TextBlock Text="{Binding Age}" Grid.Column="1"/>
<TextBlock Text="{Binding Gender}" Grid.Column="2"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AlarmTemp">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}" Grid.Column="1"/>
<TextBlock Text="{Binding Gender}" Grid.Column="2"/>
</Grid>
</DataTemplate>


</Window.Resources>
<Grid>
<ListView ItemsSource="{StaticResource datas}" >
<ListView.ItemTemplateSelector>
<!--设置两个属性-->
<local:ListViewItemTemplateSelector NormalTemplate="{StaticResource NormalTemp}" AlarmTemplate="{StaticResource AlarmTemp}"/>
</ListView.ItemTemplateSelector>
</ListView>
</Grid>
</Window>

WPF控件模板、数据模板、容器样式选择器_.net_04

容器样式选择器

也可以使用样式选择器

先创建一个ListViewStyleSelector类,继承自StyleSelector

class ListViewStyleSelector : StyleSelector
{
public Style NormalStyle { get; set; }
public Style AlarmStyle { get; set; }
public override Style SelectStyle(object item, DependencyObject container)
{
var person = item as Person;
if (person.Age > 21)
{
return AlarmStyle;
}
return NormalStyle;
}
}

XAML

<Window x:Class="WpfApp12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp12"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="400">
<Window.Resources>
<x:Array Type="local:Person" x:Key="datas">
<local:Person Name="Hello" Age="20" Gender="1"/>
<local:Person Name="Zhaoxi" Age="21" Gender="2"/>
<local:Person Name="Jovan" Age="22" Gender="1"/>
<local:Person Name="Jovan" Age="22" Gender="1"/>
<local:Person Name="Jovan" Age="18" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
<local:Person Name="Jovan" Age="24" Gender="1"/>
</x:Array>
<!--设置两个Style供选择器选择-->
<Style x:Key="NormalStyle" TargetType="ListViewItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Background="Yellow"/>
<TextBlock Text="{Binding Age}" Grid.Column="1"/>
<TextBlock Text="{Binding Gender}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="AlarmStyle" TargetType="ListViewItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}" Grid.Column="1"/>
<TextBlock Text="{Binding Gender}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ListView ItemsSource="{StaticResource datas}" >
<ListView.ItemContainerStyleSelector>
<local:ListViewStyleSelector NormalStyle="{StaticResource NormalStyle}" AlarmStyle="{StaticResource AlarmStyle}"/>
</ListView.ItemContainerStyleSelector>
</ListView>
</Grid>
</Window>

WPF控件模板、数据模板、容器样式选择器_.net_05

总结:因为style中可以设置Template属性,又可以设置样式。所以在Templat标签中完成的内容都可以可以使用Style来代替。