LogicTree 逻辑树

逻辑树显示控件的树形层级结构,但不会对控件的内部结构进行解析,例如逻辑树如下XAML,逻辑树不会把Button按钮中的ContentPresenter对象进行呈现。逻辑树更关注整个页面控件的情况,一般的查找逻辑树我们可以通过LogicTreeHelper 类进行查找。

  1. <DockPanel
  2. Name="ParentElement"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. >
  6. <!--implicit: <DockPanel.Children>-->
  7. <ListBox DockPanel.Dock="Top">
  8. <!--implicit: <ListBox.Items>-->
  9. <ListBoxItem>
  10. <TextBlock>Dog</TextBlock>
  11. </ListBoxItem>
  12. </ListBox>
  13. <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>
  14. </DockPanel>

ViualTree 可视化树

控件可以继续再继续划分成更小的元素例如,Button按钮可以拆分成对应的控件模版为如下,Button按钮还可以继续拆分为Border控件,ContentPresenter控件。这种进一步将自定义控件,系统控件拆开解析的结构称为可视化树。可以使用ViusalTreeHelper进行查找。

  1. <ControlTemplate TargetType="{x:Type Button}">
  2. <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
  3. <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
  4. </Border>
  5. </ControlTemplate>

ControlTemplate 控件模版

该模版定义了控件的外观显示,当在Sytel中设置属性Template 值是,便可对控件的外观进行重定义。定义过程中可以使用简单的TemplateBinding对模版中的值进行绑定,其等效于{Binding RelativeSource={RelativeSource TemplatedParent}} 将值绑定到父级元素,其内容如下同样含有相关的Trigger等元素。针对某些自定义属性,使用TemplateBinding如果失效可以使用Binding 来代替。

  1. <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
  2. <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
  3. <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
  4. <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
  5. <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
  6. <Setter Property="BorderThickness" Value="1"/>
  7. <Setter Property="HorizontalContentAlignment" Value="Center"/>
  8. <Setter Property="VerticalContentAlignment" Value="Center"/>
  9. <Setter Property="Padding" Value="1"/>
  10. <Setter Property="Template">
  11. <Setter.Value>
  12. <ControlTemplate TargetType="{x:Type Button}">
  13. <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
  14. <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
  15. </Border>
  16. <ControlTemplate.Triggers>
  17. <Trigger Property="IsDefaulted" Value="true">
  18. <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
  19. </Trigger>
  20. <Trigger Property="IsMouseOver" Value="true">
  21. <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
  22. <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
  23. </Trigger>
  24. <Trigger Property="IsPressed" Value="true">
  25. <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
  26. <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
  27. </Trigger>
  28. <Trigger Property="IsEnabled" Value="false">
  29. <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
  30. <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
  31. <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
  32. </Trigger>
  33. </ControlTemplate.Triggers>
  34. </ControlTemplate>
  35. </Setter.Value>
  36. </Setter>
  37. </Style>

DataTemplate 数据模版

DataTemplate 可定义为全局资源,当设置相关DataType属性后,列表控件在绑定数据时,如果数据项的类型与DataType类型一致,则会自动使用该数据模版作为项模版。

  1. <DataTemplate x:Key="teacherDataTemplate">
  2. <StackPanel Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem},Mode=FindAncestor,AncestorLevel=1}}" SnapsToDevicePixels="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
  3. <Image Source="{Binding HeadImg}" MaxWidth="250" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
  4. <TextBlock Text="{Binding Names,StringFormat=姓名:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  5. <TextBlock Text="{Binding Age,StringFormat=年龄:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  6. <TextBlock Text="{Binding Age,StringFormat=工号:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  7. </StackPanel>
  8. </DataTemplate>

ItemTeplate

  1. 主要用于数据列表控件,如ListBox,DataGrid,Tree控件等绑定时,自定义控件模版时使用
  2. 如果有多个控件模版需要使用,则需要自定义TemplateSelector来进行模版选择

综合其使用如下:

  1. <DataTemplate x:Key="stuDataTemplate" DataType="{x:Type localStore:Student}">
  2. <DataTemplate.Triggers>
  3. <DataTrigger Binding="{Binding Age}" Value="20" >
  4. <Setter Property="StackPanel.Visibility" Value="Collapsed" ></Setter>
  5. </DataTrigger>
  6. </DataTemplate.Triggers>
  7. <StackPanel Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem},Mode=FindAncestor,AncestorLevel=1}}" SnapsToDevicePixels="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
  8. <Image Source="{Binding HeadImg}" MaxWidth="250" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
  9. <TextBlock Text="{Binding Names,StringFormat=姓名:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  10. <TextBlock Text="{Binding Age,StringFormat=年龄:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  11. </StackPanel>
  12. </DataTemplate>
  13. <DataTemplate x:Key="teacherDataTemplate">
  14. <StackPanel Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem},Mode=FindAncestor,AncestorLevel=1}}" SnapsToDevicePixels="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
  15. <Image Source="{Binding HeadImg}" MaxWidth="250" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
  16. <TextBlock Text="{Binding Names,StringFormat=姓名:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  17. <TextBlock Text="{Binding Age,StringFormat=年龄:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  18. <TextBlock Text="{Binding WorkNumber,StringFormat=工号:{0}}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  19. </StackPanel>
  20. </DataTemplate>
  21. <ListBox Grid.Row="1" ItemsSource="{Binding DataContext,ElementName=windLst}" ItemTemplateSelector="{StaticResource dataTemplateSeletctor}" >
  22. <ListBox.ItemsPanel>
  23. <ItemsPanelTemplate>
  24. <WrapPanel ></WrapPanel>
  25. </ItemsPanelTemplate>
  26. </ListBox.ItemsPanel>
  27. </ListBox>
  1. public class DataTemplateSelctor : DataTemplateSelector
  2. {
  3. public DataTemplate StudTemplate { get; set; }
  4. public DataTemplate TeacherTemplate { get; set; }
  5. public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container)
  6. {
  7. var currnetItem = item as Student;
  8. if (currnetItem != null && currnetItem.IsTeacher)
  9. {
  10. return TeacherTemplate;
  11. }
  12. return StudTemplate;
  13. }
  14. }

ItemContainerTemplate 控件容器模版

该列表项的相关属性设置,也可以设置相关的Template
注意:有关的背景样式需要设置ContollerTemplate设置

  1. <Style TargetType="ListBoxItem" x:Key="stuConatinerStyler">
  2. <Setter Property="Margin" Value="0"></Setter>
  3. <Setter Property="Padding" Value="0"></Setter>
  4. <Style.Triggers>
  5. <Trigger Property="IsSelected" Value="True">
  6. <Setter Property="Background" Value="Yellow"></Setter>
  7. </Trigger>
  8. <Trigger Property="IsMouseOver" Value="True">
  9. <Setter Property="Background" Value="Red"></Setter>
  10. <Setter Property="Cursor" Value="Hand"></Setter>
  11. </Trigger>
  12. </Style.Triggers>
  13. </Style>

PanelTemplate

  1. <ListBox.ItemsPanel>
  2. <ItemsPanelTemplate>
  3. <WrapPanel ></WrapPanel>
  4. </ItemsPanelTemplate>
  5. </ListBox.ItemsPanel>

大数据列表的性能提升

  1. 虚拟化
  2. 项目容器再循环
  3. 延迟滚动