深入浅出WPF-11.Template(模板)03
模板
如果把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的更多相关文章
- 《深入浅出WPF》笔记——模板篇
原文:<深入浅出WPF>笔记--模板篇 我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法 ...
- c++11 template 模板练习
直接上代码吧 to do // 111111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> ...
- 《深入浅出WPF》笔记——资源篇
原文:<深入浅出WPF>笔记--资源篇 前面的记录有的地方已经用到了资源,本文就来详细的记录一下WPF中的资源.我们平时的“资源”一词是指“资财之源”,是创造人类社会财富的源泉.在计算机程 ...
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...
- 《深入浅出WPF》 学习笔记
<深入浅出WPF> 序言 1. 什么是WPF 2. 为什么要学习WPF 第一章 XAML概览 1. XAML是什么? 2. XAML有哪些优点 第二章 从零起步认识XAML 1. 新 ...
- 微信小程序新闻列表功能(读取文件、template模板使用)
微信小程序新闻列表功能(读取文件.template) 不忘初心,方得始终.初心易得,始终难守. 在之前的项目基础上进行修改,实现读取文件内容作为新闻内容进行展示. 首先,修改 post.wxml 文件 ...
- django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统
Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...
- WPF 详解模板
在WPF中有三大模板 ControlTemplate,ItemsPanelTemplate,DataTemplate.其中ControlTemplate和 ItemsPanelTemplate是控件模 ...
- 【【分享】深入浅出WPF全系列教程及源码
】
因为原书作者的一再要求,在此声明,本书中的部分内容引用了原书名为<深入浅出WPF>的部分内容,假设博文不能满足你现有的学习须要,能够购买正版图书! 本人10月份提出离职,可是交接非常慢,预 ...
- 《深入浅出WPF》笔记——绘画与动画
<深入浅出WPF>笔记——绘画与动画 本篇将记录一下如何在WPF中绘画和设计动画,这方面一直都不是VS的强项,然而它有一套利器Blend:这方面也不是我的优势,幸好我有博客园,能记录一 ...
随机推荐
- java8 lambda 表达式详解
lambada 表达式实质上是一个匿名方法,但该方法并非独立执行,而是用于实现由函数式接口定义的唯一抽象方法 使用 lambda 表达式时,会创建实现了函数式接口的一个匿名类实例 可以将 lambda ...
- 1、Spark简介(Python版)
此文为个人学习笔记如需系统学习请访问http://dblab.xmu.edu.cn/blog/1709-2/ Spark具有如下几个主要特点: 运行速度快 Spark使用先进的DAG(Dir ...
- JAVA中的策略模式strategy
原文出自:http://ttitfly.iteye.com/blog/136467 1. 以一个算术运算为例,传统做法为: java 代码 package org.common; public cla ...
- 使用dom4j工具:读取xml标签(二)
package dom4j_read; import java.io.File; import java.util.List; import org.dom4j.Document; import or ...
- kubebuilder实战之五:operator编码
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 【C语言】第2章 算法 — 程序的灵魂
第2章 算法 - 程序的灵魂 一个程序主要包括以下两方面的信息: 对数据的描述.在程序中要指定用到哪些数据以及这些数据的类型和数据的组织形式 也就是数据结构(data structure) 对操作的描 ...
- Spring Boot +Vue 项目实战笔记(一):使用 CLI 搭建 Vue.js 项目
前言 从这篇文章开始,就进入真正的实践了. 在前端项目开发中,我们可以根据实际情况不同程度地使用 Vue.利用 Vue CLI(或写成 vue-cli,即 Vue 脚手架)搭建出来的项目,是最能体现 ...
- MySQL高可用主从复制简介
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 简介 1.1 概述 二 技术原理 2.1 支持的复制类型 2.2 技术特点 2 ...
- linux centos7 命令中的 2>&1 代表的意义
2021-09-01 1. 参数介绍 0 – stdin (standard input) 标准输入1 – stdout (standard output) 标准输出2 – stderr (stand ...
- Qt 自定义事件
Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...