LogicTree 逻辑树
逻辑树显示控件的树形层级结构,但不会对控件的内部结构进行解析,例如逻辑树如下XAML,逻辑树不会把Button按钮中的ContentPresenter对象进行呈现。逻辑树更关注整个页面控件的情况,一般的查找逻辑树我们可以通过LogicTreeHelper
类进行查找。
<DockPanel
Name="ParentElement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<!--implicit: <DockPanel.Children>-->
<ListBox DockPanel.Dock="Top">
<!--implicit: <ListBox.Items>-->
<ListBoxItem>
<TextBlock>Dog</TextBlock>
</ListBoxItem>
</ListBox>
<Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>
</DockPanel>
ViualTree 可视化树
控件可以继续再继续划分成更小的元素例如,Button按钮可以拆分成对应的控件模版为如下,Button按钮还可以继续拆分为Border控件,ContentPresenter控件。这种进一步将自定义控件,系统控件拆开解析的结构称为可视化树。可以使用ViusalTreeHelper
进行查找。
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
ControlTemplate 控件模版
该模版定义了控件的外观显示,当在Sytel中设置属性Template
值是,便可对控件的外观进行重定义。定义过程中可以使用简单的TemplateBinding
对模版中的值进行绑定,其等效于{Binding RelativeSource={RelativeSource TemplatedParent}}
将值绑定到父级元素,其内容如下同样含有相关的Trigger等元素。针对某些自定义属性,使用TemplateBinding如果失效可以使用Binding 来代替。
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
DataTemplate 数据模版
DataTemplate 可定义为全局资源,当设置相关DataType属性后,列表控件在绑定数据时,如果数据项的类型与DataType类型一致,则会自动使用该数据模版作为项模版。
<DataTemplate x:Key="teacherDataTemplate">
<StackPanel Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem},Mode=FindAncestor,AncestorLevel=1}}" SnapsToDevicePixels="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Image Source="{Binding HeadImg}" MaxWidth="250" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
<TextBlock Text="{Binding Names,StringFormat=姓名:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding Age,StringFormat=年龄:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding Age,StringFormat=工号:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
</StackPanel>
</DataTemplate>
ItemTeplate
- 主要用于数据列表控件,如ListBox,DataGrid,Tree控件等绑定时,自定义控件模版时使用
- 如果有多个控件模版需要使用,则需要自定义TemplateSelector来进行模版选择
综合其使用如下:
<DataTemplate x:Key="stuDataTemplate" DataType="{x:Type localStore:Student}">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Age}" Value="20" >
<Setter Property="StackPanel.Visibility" Value="Collapsed" ></Setter>
</DataTrigger>
</DataTemplate.Triggers>
<StackPanel Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem},Mode=FindAncestor,AncestorLevel=1}}" SnapsToDevicePixels="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Image Source="{Binding HeadImg}" MaxWidth="250" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
<TextBlock Text="{Binding Names,StringFormat=姓名:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding Age,StringFormat=年龄:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="teacherDataTemplate">
<StackPanel Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem},Mode=FindAncestor,AncestorLevel=1}}" SnapsToDevicePixels="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Image Source="{Binding HeadImg}" MaxWidth="250" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
<TextBlock Text="{Binding Names,StringFormat=姓名:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding Age,StringFormat=年龄:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding WorkNumber,StringFormat=工号:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
</StackPanel>
</DataTemplate>
<ListBox Grid.Row="1" ItemsSource="{Binding DataContext,ElementName=windLst}" ItemTemplateSelector="{StaticResource dataTemplateSeletctor}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
public class DataTemplateSelctor : DataTemplateSelector
{
public DataTemplate StudTemplate { get; set; }
public DataTemplate TeacherTemplate { get; set; }
public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container)
{
var currnetItem = item as Student;
if (currnetItem != null && currnetItem.IsTeacher)
{
return TeacherTemplate;
}
return StudTemplate;
}
}
ItemContainerTemplate 控件容器模版
该列表项的相关属性设置,也可以设置相关的Template
注意:有关的背景样式需要设置ContollerTemplate设置
<Style TargetType="ListBoxItem" x:Key="stuConatinerStyler">
<Setter Property="Margin" Value="0"></Setter>
<Setter Property="Padding" Value="0"></Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Yellow"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Cursor" Value="Hand"></Setter>
</Trigger>
</Style.Triggers>
</Style>
PanelTemplate
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
大数据列表的性能提升
- 虚拟化
- 项目容器再循环
- 延迟滚动