常用 ControlTemplate 的地方:Control 的 Template 属性

运用效果举例:穿着 CheckBox 外衣的 ToggleButton,披着温度计的 ProgressBar。

好处:

  1. 通过更换 ControlTemplate 改变控件外观,使之具有更优的用户使用体验及外观;
  2. 并行开发,程序员先用 WPF 标准控件进行编程,等设计师的工作完成后,只需要把新的 ControlTemplate 应用到程序中。

1. ControlTemplate 使用

<Style x:Key="RoundCornerTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Background="{Binding RelativeSource={RelativeSource TemplatedParent}}" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style> <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>

还记得 RelativeSource 中 Mode 枚举值之一 TemplatedParent?

BorderBrush="{TemplateBinding BorderBrush}" 等价于

BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}

再一次回到 LogicalTree 和 VisualTree,它们的交点就是 ControlTemplate,LogicalTree 的导航不会进入控件的内部,而在 VisualTree 上导航就能检索到控件内部由 ControlTemplate 生成的子级控件。

2. ItemsControl 的 ItemsPanel 属性

数据类型是 ItemsPanelTemplate,也属于一种控件 Template;

作用:控制 ItemsControl 的条目容器。

<!--默认纵向排序-->
<ListBox>
<TextBlock Text="a"/>
<TextBlock Text="b"/>
<TextBlock Text="c"/>
</ListBox> <!--过 ItemsControl 的 ItemsPanel 修改成横向排序-->
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel> <TextBlock Text="a"/>
<TextBlock Text="b"/>
<TextBlock Text="c"/>
</ListBox>

最新文章

  1. siteMap与站点导航
  2. C#数据库导出(入)TXT
  3. OpenLayers 3 基础知识(一)
  4. Centos ftp服务器安装配置
  5. POJ 1127 Jack Straws(计算几何)
  6. 一种swift编码风格指南(供参考,by linkedin)
  7. Windows安装Python包下载工具pip遇到的问题
  8. C#中ToString和Formate格式大全
  9. 从零开始,打造自己的首个 iOS 框架
  10. 在code.org上自己写一个flappy bird游戏
  11. C#避免过长的IF和Switch分支的方法
  12. python 打印类的属性、方法
  13. 【转】JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法
  14. ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证
  15. 你不知道你不懂javascript
  16. 基于fastadmin快速搭建后台管理
  17. vue 学习笔记—路由篇
  18. 安装mysql出现no compatible servers were found
  19. MVC Form验证 登陆和退出Cookies的设定和消除
  20. 【learning】微信跳一跳辅助c++详解 轻松上万 【上】

热门文章

  1. QT串口助手(五):文件操作
  2. Pod 实现机制
  3. WOJ1024 (POJ1985+POJ2631) Exploration 树/BFS
  4. 012.NET5_MVC_Razor布局
  5. how to input special symbol in macOS
  6. JWT &amp; JSON Web Tokens
  7. js form.onformData事件
  8. nasm win x86 hello world
  9. NGK内存爆发式增长,看Baccarat将怎样打造全新的全场景金融生态
  10. JUnit5学习之一:基本操作