模板

如果把WPF窗体看做一个舞台的话,窗体上的控件就是演员,他们的职责就是在用户界面上按照业务逻辑的需呀哦扮演自己的角色。为了让同一个控件担当起不同的角色,程序员就要为他们设计多种外观样式和行为动作。这就是Style。构成Style 的两个重要元素就是Setter和Trigger,Setter是用来设置控件的静态外观风格,Trigger是用来设置控件的行为风格。

<Style x:Key="ListBoxOCTStyle" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{StaticResource ListBoxPopBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource ListBoxPopBorderBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
<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
Padding="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ScrollViewer
Padding="{TemplateBinding Padding}"
Focusable="false"
Template="{StaticResource ScrollViewerControlTemplate}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<Style BasedOn="{StaticResource ListBoxOCTItemStyle}" TargetType="ListBoxItem" />
</Style.Resources>
</Style>

根据上面的例子我们可以看出,如果想设置控件的ControlTemplate,只需要把Setter的Property设置为Template并为Value提供一个ControlTemplate对象即可。

Trigger(触发器)即当某些条件满足时会触发一个行为(比如某些值的变化或者动画的发生等),触发器比较像事件。事件一般是由用户操作触发的,而触发器除了事件触发型 的EventTrigger外,还有数据变化触发型的Trigger/DataTrigger及多条件触发型的MultiTrigger/MultiDataTrigger等。

1)基本触发器Trigger:类似于Setter,也有Property和Value两个属性,Property是Trigger关注的属性名称,Value是触发条件。一旦满足这个条件,对应的值就会被应用,触发条件不满足时,各属性值就会被还原。

<Style x:Key="ListBoxOCTItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="Auto" />
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="ContentTemplate" Value="{StaticResource ListBoxItemOCTDataTemplate}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
x:Name="Bd"
Margin="0,1"
Padding="{TemplateBinding Padding}"
Background="{StaticResource ItemSelectedBackground}"
BorderBrush="{StaticResource ItemSelectedBackground}"
BorderThickness="2,2,2,2"
CornerRadius="5"
SnapsToDevicePixels="true">
<Grid x:Name="grid">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="YellowGreen" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="#FF126BAA" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}"/>-->
<!--<Setter Property="Foreground" Value="{StaticResource CommonForeground}"/>-->
<!--<Setter Property="BorderBrush" Value="YellowGreen"/>
<Setter Property="BorderThickness" Value="2,2,2,2"/>-->
</Trigger>
<Trigger Property="IsSelected" Value="True">
<!--<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}"/>-->
<!--<Setter Property="Foreground" Value="{StaticResource CommonForeground}"/>-->
<!--<Setter Property="BorderBrush" Value="#FF126BAA"/>-->
<!--<Setter Property="BorderThickness" Value="2,2,2,2"/>-->
</Trigger>
</Style.Triggers>
</Style>

2)MultiTrigger,类似于MultiBinding,只有多条件都满足时才会触发。MultiTrigger比Trigger多了一个Conditions属性,需要同时满足的条件就放在这个集合中。

<Style x:Key="DataGridScrollBarEverShowStyle" TargetType="DataGrid">
<Setter Property="Background" Value="{DynamicResource SecondaryRegionBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="GridLinesVisibility" Value="None" />
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="HorizontalScrollBarVisibility" Value="Visible" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="EnableRowVirtualization" Value="True" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="CanUserReorderColumns" Value="False" />
<Setter Property="CanUserResizeRows" Value="False" />
<Setter Property="CanUserResizeColumns" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGrid">
<Border
……
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
</Style.Triggers>
</Style>

3)由数据触发的DataTrigger:程序中经常会遇到基于数据执行某些判断的情况,遇到这种情况时我们可以考虑使用DataTrigger。DataTrigger对象Binding属性会把数据源不断的送过来,一旦送来的值与Value值一致时,DataTrigger就会触发。

<!--  ItemsControl分组  -->
<Style x:Key="GroupContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Width" Value="200" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsBottomLevel}" Value="True">
<Setter TargetName="gridTemplate" Property="Grid.Background" Value="Gray" />
</DataTrigger>
</ControlTemplate.Triggers>
<Border BorderBrush="{StaticResource CommonBackground}" BorderThickness="0,2,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid
x:Name="gridTemplate"
Width="{TemplateBinding Width}"
Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{StaticResource DarkBackground}">
<Border
Height="Auto"
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="Black"
BorderThickness="0">
<ToggleButton
x:Name="btnShowHide"
Width="Auto"
Height="Auto"
IsChecked="True"
Style="{StaticResource ToggleButtonStyle}" />
</Border>
<!--<Label Content="{Binding Path=Name}" Grid.Column="0" VerticalContentAlignment="Center"/>-->
<!--<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Column="1" Content="{Binding Path=ItemCount, StringFormat=Total:{0}}"/>-->
</Grid>
<ItemsPresenter
Grid.Row="1"
Margin="0"
Visibility="{Binding ElementName=btnShowHide, Path=IsChecked, Converter={StaticResource booleanToVisibilityConverter}}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

4)多数据条件触发的MultiDataTrigger:当多个数据条件满足时就会触发的情况下,就可以使用多数据条件触发器。这里结合多条件触发器和数据触发器就可以很容易理解了。

5)事件触发器EventTrigger:事件触发器比较特殊,首先,他不是属性值或者数据的变化来触发而是由事件触发的;其次,被触发后并非应用一组Setter,而是执行一段动画

<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard Storyboard="{StaticResource Storyboard2}"/>
</EventTrigger>
</ControlTemplate.Triggers>

有上面的这些代码可以看出,触发器不一定非要应用在Style中,在Template中也可以使用触发器。比如:

<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="YellowGreen" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="#FF126BAA" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

深入浅出WPF-11.Template(模板)03的更多相关文章

  1. 《深入浅出WPF》笔记——模板篇

    原文:<深入浅出WPF>笔记--模板篇 我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法 ...

  2. c++11 template 模板练习

    直接上代码吧 to do // 111111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> ...

  3. 《深入浅出WPF》笔记——资源篇

    原文:<深入浅出WPF>笔记--资源篇 前面的记录有的地方已经用到了资源,本文就来详细的记录一下WPF中的资源.我们平时的“资源”一词是指“资财之源”,是创造人类社会财富的源泉.在计算机程 ...

  4. 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异

    编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...

  5. 《深入浅出WPF》 学习笔记

    <深入浅出WPF> 序言 1. 什么是WPF    2. 为什么要学习WPF 第一章 XAML概览 1. XAML是什么? 2. XAML有哪些优点 第二章 从零起步认识XAML 1. 新 ...

  6. 微信小程序新闻列表功能(读取文件、template模板使用)

    微信小程序新闻列表功能(读取文件.template) 不忘初心,方得始终.初心易得,始终难守. 在之前的项目基础上进行修改,实现读取文件内容作为新闻内容进行展示. 首先,修改 post.wxml 文件 ...

  7. django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统

    Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...

  8. WPF 详解模板

    在WPF中有三大模板 ControlTemplate,ItemsPanelTemplate,DataTemplate.其中ControlTemplate和 ItemsPanelTemplate是控件模 ...

  9. 【【分享】深入浅出WPF全系列教程及源码 】

    因为原书作者的一再要求,在此声明,本书中的部分内容引用了原书名为<深入浅出WPF>的部分内容,假设博文不能满足你现有的学习须要,能够购买正版图书! 本人10月份提出离职,可是交接非常慢,预 ...

  10. 《深入浅出WPF》笔记——绘画与动画

    <深入浅出WPF>笔记——绘画与动画   本篇将记录一下如何在WPF中绘画和设计动画,这方面一直都不是VS的强项,然而它有一套利器Blend:这方面也不是我的优势,幸好我有博客园,能记录一 ...

随机推荐

  1. 把 nodejs koa2 制作的后台接口 部署到 腾讯云服务器

    我 使用 nodejs koa2框架 制作后端接口, 现在将nodejs koa2 部署到服务器 koa2项目 实现 接口 可以看我的 这篇文章: 简单实现 nodejs koa2 mysql 增删改 ...

  2. Java基础和常用框架的面试题

    前言 最近学校也催着找工作了,于是刷了一些面试题,学习了几篇大佬优秀的博客,总结了一些自认为重要的知识点:听不少职场前辈说,对于应届毕业生,面试时只要能说到核心重要的点,围绕这个点说一些自己的看法,面 ...

  3. python操作图片

    时间:2018-11-30 记录:byzqy 标题:python实现图片操作 地址:https://blog.csdn.net/baidu_34045013/article/details/79187 ...

  4. Windows-MacOSX-Ubuntu·不同平台文件互传文件共享

    时间:2018-11-23 整理:byzqy 标题:Mac下的virtual box 安装的Ubuntu虚拟机互传文件问题 地址:https://blog.csdn.net/qq_20044689/a ...

  5. mysql各个版本驱动jar包下载 mysql/mysql-connector-java/5.1.22

    想下个jar csdn上全是要积分下载,这里记录下 下载地址,免得到时又要找 http://central.maven.org/maven2/mysql/mysql-connector-java/

  6. eBPF 安全项目 Tracee 初探

    1. Tracee 介绍 1.1 Tracee 介绍 Tracee 是一个用 于 Linux 的运行时安全和取证工具.它使用 Linux eBPF 技术在运行时跟踪系统和应用程序,并分析收集的事件以检 ...

  7. Python - 面向对象编程 - 小实战(1)

    题目 设计一个类Person,生成若干实例,在终端输出如下信息 小明,10岁,男,上山去砍柴 小明,10岁,男,开车去东北 小明,10岁,男,最爱大保健 老李,90岁,男,上山去砍柴 老李,90岁,男 ...

  8. 腾讯与Intel就云游戏的探讨

    今天去参加了在腾讯北京总部的腾讯音视频技术 HUB 技术巡回大会,对其中的云游戏应用的探讨格外感兴趣.正巧最近元宇宙概念很火,这篇文章就大会中对云游戏的探讨进行总结和汇报. 讲述一下来自Intel的工 ...

  9. openswan发送状态机分析

    openswan发送状态机分析 1. 函数调用关系 2. 函数说明 如果按用户空间.内核空间划分的话,此部分代码更多是运行在内核空间的. 2.1 ipsec_tunnel_init_devices() ...

  10. 制作Windows服务和安装程序(C#版)

    http://blog.sina.com.cn/s/blog_5f4ffa170100vt2b.html 1.创建服务项目: 打开VS 2005 编程环境,在C#中新建Windows服务程序 2.将安 ...