当前位置:网站首页>WPF WPF 】 【 the depth resolution of the template
WPF WPF 】 【 the depth resolution of the template
2022-07-31 04:29:00 【code beans】
举几个例子
1 ItemsPanelTemplate(子项容器模板)
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<!--布局的时候,Children are dynamically bound-->
<Canvas/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
ListView的ItemsPanel的类型为ItemsPanelTemplate,
2 DataTemplate(数据模板)
<ListView.ItemTemplate>
<DataTemplate>
<Grid Canvas.Left="{Binding Left}" Canvas.Top="{Binding Top}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
ListView的ItemTemplate属性的类型是DataTemplate
3 ControlTemplate(控件模板)
而Button的Template属性的类型是ControlTemplate,Actually any controlTemplate属性的类型都是
ControlTemplate,如Button:
<Button DataContext="{StaticResource datas}" Height="50">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid DataContext="{Binding [0]}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}" Grid.Column="1"/>
</Grid>
</ControlTemplate>
Avoid two pits
To understand templates,The first pit to avoid is,Template property namesumTemplate type name.Don't differentiate this thing,You would mistakenly think that there are many template types,directly scared,劝退.
Template property and template type for each control,is the relationship between the instance and the class,这里一定注意!
其次,要认识到,The following syntax is not nesting,It's the assignment of properties,是一个实例化的过程:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<!--布局的时候,Children are dynamically bound-->
<Canvas/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
ListView的ItemsPanel属性的类型为ItemsPanelTemplate,So here is one written in itItemsPanelTemplate,This indicates that one is instantiatedItemsPanelTemplate对象并赋值给ListView的ItemsPanel属性.
逻辑树和视觉树
Talk about templates,The visual tree cannot be avoided,First look at the logic tree,这个很简单,Because it is so intuitivexamlNest these in“业务逻辑”:
<Window x:Class="Zhaoxi.WPFLession.Window1"
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:Zhaoxi.WPFLession"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<UniformGrid Rows="2" Columns="2">
<Button>
<TextBox>asdfasdf</TextBox>
</Button>
<TextBox Width="100" Height="30">123456</TextBox>
<TextBlock Width="100" Height="30" Background="AliceBlue">sdfad</TextBlock>
</UniformGrid>
</Window>
Now the logical tree of the above code,就是:Window -》UniformGrid-》Button-》TextBox (I will not draw the parallel relationship)
视觉树,It depends on the inside of the control,比如Button这个控件,is built from more basic elements,It's just that it's encapsulated and we can't see the details,But you can seebuttonThere is text in the middle,The background is gray.
接下来,We can use the function of editing templates,观察一下,Button的内部世界(视觉树):
选中Button,右键选择=》编辑模板
<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" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 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>
这里通过Style设置了button的所有属性,But here we focus onTemplate这个属性!Here is the presentation of the visual tree.Then we find the compositionbutton的元素部分,异常的简单:
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
一个 border里面放了一个ContentPresenter(数据模板相关,后面讲解) .And these are contained in a package called ControlTemplate的标签里.
ControlTemplate
ControlTemplateA control template provides an interface for modifying the visual tree!I want to see nextListbox的控件模板,方法一样:
<Style x:Key="ListBoxStyle1" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{StaticResource ListBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ListBox.Static.Border}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1" SnapsToDevicePixels="true">
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Border}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
There are also not many elements:
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1" SnapsToDevicePixels="true">
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
最后我想看看TextBlock的ControlTemplate,然而你会发现TextBlock根本没有ControlTemplate,Because he is not a control at all,他直接继承自FrameworkElement,It's just an element.(包括Border和ItemPresenter以及ContentPresenter都是继承FrameworkElementand not directly inherited fromControl)
那么这里,我总结一下:
The inside of each control in the logical tree actually contains the visual tree.The visual tree is also composed of basic elements and controls!Because the visual tree is encapsulated,So Microsoft offers programmers to modify the internals of the control(视觉树)的机会,及控件模板.修改控件模板,The appearance of the controls can be easily changed!举个例子:
这两个都是checkbox,We don't need to override the control,Just need to modify the logic tree through the control template as wellTrigger就能实现.(Trigger下一篇再说)
注意:这里指定TargetType是很重要的,不然IsCheckedThis property fails to compile
<CheckBox Width="100" Height="50" >
<CheckBox.Template>
<ControlTemplate TargetType="CheckBox">
<Border Background="AliceBlue">
<Canvas>
<Rectangle x:Name="rt" Fill="Orange" Width="50" Height="50"/>
</Canvas>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="rt" Property="Canvas.Left" Value="50"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>
DataTemplate
Next is the data template,He also wants to see the visual tree in this lesson,in the previous visual tree,We found something we didn't recognize,But basically there is him in the visual tree:ItemPresenter以及ContentPresenter(以Presenter结尾的东西)
这些以Presenter结尾的元素,统称为“内容占位”.为啥wpfThe controls can be nested arbitrarily?奥秘就在这里,如果你给buttonSomething nested inside,This thing will be thrownContentPresenter,ContentPresenterwill wrap it up.而PresenterThe element at the end is also the object of the data template.
举个例子:
<Window x:Class="Zhaoxi.WPFLession.Window1"
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:Zhaoxi.WPFLession"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Window.Resources>
<x:Array Type="local:Person" x:Key="datas">
<local:Person Name="啊啊啊" Age="20" Gender="1"/>
<local:Person Name="呃呃呃" Age="21" Gender="2"/>
<local:Person Name="哦哦哦" Age="21" Gender="2"/>
<local:Person Name="呵呵呵" Age="21" Gender="2"/>
</x:Array>
</Window.Resources>
<UniformGrid Rows="2" Columns="2">
<ListBox ItemsSource="{StaticResource datas}">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel LastChildFill="False">
<TextBlock DockPanel.Dock="Right" Text="{Binding Name}"/>
<CheckBox/>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UniformGrid>
</Window>
效果如下:
用snoopTake a look at the internal structure of our program:
You found threePresenter结尾的元素,
一个ScrollContentPresenter是属于ListBoxof visual tree speciesScrollView的,ScrollContentPresenter就包含了ItemsPresenter,contains a series ofListBoxItem,而ListBoxItemIt contains what we defined in the data templateDataTemplate的内容:
小结,数据模板,In fact, it can also change the visual tree,It's just that he doesn't re-modify the entire visual tree of the control,而是向PresenterAdd content to the element at the end.And these contents need to be bound to the data data will be instantiated.
ItemsPanelTemplate,This is tiring today,后续补充吧.
总结:
1 We need to avoid two pits
2 Understand what a visual tree is
3 Both data templates and control templates are interfaces provided by Microsoft,Used to modify the visual tree.
边栏推荐
- unity2d小游戏
- npm、nrm两种方式查看源和切换镜像
- errno错误码及含义(中文)
- 【论文阅读】Mastering the game of Go with deep neural networks and tree search
- MySQL修改root账号密码
- 问题7:列表的拼接
- MATLAB/Simulink&&STM32CubeMX工具链完成基于模型的设计开发(MBD)(三)
- MySQL fuzzy query can use INSTR instead of LIKE
- Know the showTimePicker method of the basic components of Flutter
- Port inspection steps - 7680 port analysis - Dosvc service
猜你喜欢
ERROR 2003 (HY000) Can‘t connect to MySQL server on ‘localhost3306‘ (10061)
(四)递归、可变参数、访问修饰符、理解 main 方法、代码块
Regarding the primary key id in the mysql8.0 database, when the id is inserted using replace to be 0, the actual id is automatically incremented after insertion, resulting in the solution to the repea
Know the showTimePicker method of the basic components of Flutter
C语言表白代码?
MySQL数据库必会的增删查改操作(CRUD)
$attrs/$listeners
SOLVED: After accidentally uninstalling pip (two ways to manually install pip)
Recursive implementation of the Tower of Hanoi problem
强化学习:从入门到入坑再到拉屎
随机推荐
C语言从入门到如土——数据的存储
IDEA常用快捷键与插件
已解决:不小心卸载pip后(手动安装pip的两种方式)
BP神经网络
open failed: EACCES (Permission denied)
interprocess communication
pom文件成橘红色未加载的解决方案
(tree) Last Common Ancestor (LCA)
Exsl file preview, word file preview web page method
Daily practice of LeetCode - 138. Copy a linked list with random pointers
ERROR 1819 (HY000) Your password does not satisfy the current policy requirements
Musk talks to the "virtual version" of Musk, how far is the brain-computer interaction technology from us
"A daily practice, happy water problem" 1331. Array serial number conversion
No qualifying bean of type 问题
qlib架构
exsl文件预览,word文件预览网页方法
Safety 20220722
Postgresql 15 source code analysis (5) - pg_control
prompt.ml/15中<svg>标签使用解释
The use of beforeDestroy and destroyed