WPF中样式和行为和触发器
样式简介:样式(style)是组织和重用格式化选项的重要工具,不是使用重复的标记填充XAML,以便设置外边距、内边距、颜色以及字体等细节。而是创建一系列封装所有这些细节的样式,然后在需要之处通过属性来设置样式。名称空间是System.Windows。
1、样式。
为了理解适合使用样式的集合,分析一个简单的示例,设想需要标准化在窗口中使用的字体,最简单的方式是设置包含窗口的字体属性,这些属性都是在Control类中定义的,包括FontFamily、FontSize、FontWeight,得益于这些属性值的继承,当在窗口级别设置这些属性时,窗口中的所有元素都会使用相同的属性值。
定义一个普通的资源:
<Window.Resources>
<!-- 定义一个FontFamily资源对象 -->
<FontFamily x:Key="TextBlockFontFamily">楷体</FontFamily>
<!-- 定义一个FontWeight资源对象 -->
<FontWeight x:Key="TextBlockFontWeight">Bold</FontWeight>
</Window.Resources>
定义一个TextBlock,引用资源:
<TextBlock FontFamily="{StaticResource TextBlockFontFamily}" FontSize="30" FontWeight="{StaticResource TextBlockFontWeight}">今天天气好晴朗!!!</TextBlock>
在使用资源设置属性时,正确地匹配类型是非常重要的,这个时候用到的是类型转换器,如果为元素设置FontFamily对象,FontFamilyConverter转换器会创建所需要的FontFamily对象。
这种写法的弊端:
除了资源名称相似外,并没有明确指明这三个资源是相关的,这使维护变得非常复杂。
需要使用资源的标记非常繁琐。
这个时候样式就可以很好地解决这种解决方案(定义样式):
<Window.Resources>
<Style x:Key="TextBlockStyle">
<Setter Property="Control.FontFamily" Value="楷体"></Setter>
<Setter Property="Control.FontSize" Value="20"></Setter>
<Setter Property="Control.FontWeight" Value="Bold"></Setter>
</Style>
</Window.Resources>
名叫TextBlockStyle的样式对象包含了一个设置器集合,该集合包含了三个Setter对象,每一个Setter对象用于一个希望设置的属性,每个setter属性对象由两部分信息组成,分别是希望进行设置的属性名称和希望为该属性应用的值。与所有资源一样,样式和对象都有一个键名。
在xaml中引用:
<TextBlock Name="TextBlock1" Style="{StaticResource TextBlockStyle}">Hello,World!!!</TextBlock>
用代码设置:
TextBlock1.Style = (Style)FindResource("TextBlockStyle");
2、Style类的常用属性。
Style类的常用属性 |
|
属性名 |
说明 |
Setters |
设置属性值以及自动关联事件处理程序的Setter对象或者EventSetter对象的集合。 |
Triggers |
继承自TriggerBase类,并能自动改样式设置对象的集合,例如当某个属性改变时,或者是发生某个事件时,可以修改样式。 |
Resources |
希望用于样式的资源集合。 |
BaseOn |
通过该属性可用于创建继承自其他样式设置的更具体形式。 |
TargetType |
该属性标识应用央视的元素的类型,通过该属性可创建只影响特定类型元素的设置器,还可以创建能够为恰当的元素类型自动其作用的设置器。 |
3、创建样式对象(嵌套元素)。
每一个Style对象都封装了一个Setter对象的集合,每个Setter对象设置元素的单个属性,只能设置依赖项属性,不能修改其他属性。
<TextBlock Text="孤独和迷茫时成长的必经之路!">
<TextBlock.Style>
<Style>
<Setter Property="Control.FontWeight" Value="Bold"></Setter>
<Setter Property="Control.FontSize" Value="20"></Setter>
</Style>
</TextBlock.Style>
</TextBlock>
4、设置元素类型(TargetType)并自动应用样式。
通过TargetType指定类类型。如果去掉x:key特性,那么就会自动应用到元素类型了。将元素的Style属性设置为x:Null 可取消自动应用样式。
<!--如果不写x:key特性,就会自动为类元素设置style样式了,不用再通过元素的style属性设置样式了。-->
<Window.Resources>
<Style TargetType="Button" >
<Setter Property="Control.FontFamily" Value="楷体"></Setter>
<Setter Property="Control.FontWeight" Value="Bold"></Setter>
<Setter Property="Control.FontSize" Value="30"></Setter>
</Style>
</Window.Resources> <StackPanel>
<Button Height="50">孤独和时成长的必经之路!</Button>
<!--通过x:Null取消样式设置。-->
<Button Height="50" Style="{x:Null}">孤独和时成长的必经之路!</Button>
</StackPanel>
6、多层样式(通过BaseOn继承)。
尽管可在许多不同层次定义任意数量的样式,但每个WPF元素一次只能使用一个样式对象。这好像是一种限制,但由于属性值继承和样式继承特性,可通过BaseOn属性继承样式即可。 如果两次设置了同一个属性,那么最后一次设置的样式会覆盖之前设置的样式。
<Window.Resources>
<!--设置一个字体样式-->
<Style x:Key="SetButtonFontSize">
<Setter Property="Control.FontSize" Value="30"></Setter>
</Style> <!--设置一个字体类型样式,通过BaseOn属性继承字体大小样式-->
<Style x:Key="SetButtonFontFamily" BasedOn="{StaticResource SetButtonFontSize}">
<Setter Property="Control.FontFamily" Value="楷体"></Setter>
</Style> <!--设置一个字体粗细,通过BaseOn属性继承字体类型,这样这个样式就拥有了字体类型的字体大小的样式了-->
<Style x:Key="SetButtonBold" BasedOn="{StaticResource SetButtonFontFamily}">
<Setter Property="Control.FontWeight" Value="Bold"></Setter>
<!--如果再设置字体大小,那么就以最后一次设置为准。-->
<Setter Property="Control.FontSize" Value="40"></Setter>
</Style>
</Window.Resources> <StackPanel>
<Button Style="{StaticResource SetButtonBold}">Hello,World!!!</Button>
</StackPanel>
7、触发器(Trigger)。
WPF有个主题,就是以声明的方式扩展代码的功能,当使用样式、资源或者数据绑定时,将发现即使不适用代码,也能完成不少工作,这个时候就要使用触发器了,当属性发生变化时,可以进行响应,并自动调整样式。每个样式可以有任意多个触发器,而且每个触发器都是System.Windows.TriggerBase的派生类的实例。
简单理解就是:在样式中设置触发器,在触发器中设置属性名称和属性值。
继承自TriggerBase的类 |
|
Trigger |
这是一种简单的触发器,可以监测依赖项属性的变化,然后使用设置器改变样式 |
MultiTrigger |
与Trigger类似,但这种触发器联合了多个条件,只有满足了所有这些条件,才会启动出触发器 |
DataTrigger |
数据绑定触发器 |
MultiDataTrigger |
联合多个数据触发器 |
EventTrigger |
这是复杂的触发器,当事件发生时,这种触发器应用动画 |
7.1、简单触发器。
可以为任何依赖项属性关联简单触发器,每个简单的触发器都指定了正在监视的属性,以及正在等待的属性值,当属性值出现时,将应用存储在Trigger.Setters集合中的设置器(不能使用复杂的触发器逻辑)。
<Window.Resources>
<Style x:Key="BigFontButton">
<Style.Setters>
<Setter Property="Control.FontSize" Value="30"></Setter>
<Setter Property="Control.FontFamily" Value="楷体"></Setter>
</Style.Setters> <!--在样式中设置触发器-->
<Style.Triggers>
<!--如果元素获取了焦点。-->
<Trigger Property="Control.IsFocused" Value="true">
<!--设置其中的元素属性。设置前景色为紫色。-->
<Setter Property="Control.Foreground" Value="Pink"></Setter>
</Trigger>
</Style.Triggers>
</Style> <!--设置一个简单的触发器,在触发器中改变元素的背景色。-->
<Style x:Key="SetButton">
<Style.Triggers>
<Trigger Property="Control.IsFocused" Value="true">
<Setter Property="Control.Background" Value="Yellow"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources> <StackPanel>
<!--设置第一个样式-->
<Button Style="{StaticResource BigFontButton}">Hello,World!!!</Button>
<!--设置第二个样式-->
<Button Style="{StaticResource SetButton}" Height="50" FontSize="30">Hello,World!!!</Button>
</StackPanel>
7.2、为元素设置样式(嵌套形式)。
<Button Height="50" FontSize="30" Content="今天天气好晴朗!!!">
<Button.Style>
<Style>
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="true">
<!--可将S属性样式写在Trigger.Setters中(方式一)-->
<!--<Trigger.Setters>
<Setter Property="Control.Foreground" Value="Red"></Setter>
</Trigger.Setters>--> <!--(方式二)-->
<!--也可以直接写在Triggr中,视情况而定,如果触发器满足多个条件时,要使用第一种方式设置属性值。-->
<Setter Property="Control.Foreground" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
7.3、MultiTrigger触发器(满足多条件的触发器)。
如果希望创建只有当几个条件都为真时才激活的触发器,可使用MultiTrigger,这种触发器提供了一个Conditions(条件)集合,可通过该集合定义一系列属性值的集合。
<Window.Resources>
<Style x:Key="SetButton">
<!--触发器-->
<Style.Triggers>
<!--使用多条件触发器-->
<MultiTrigger>
<!--通过Conditions属性设置多个条件(一个是获取焦点和鼠标移动到元素上。)。-->
<MultiTrigger.Conditions>
<Condition Property="Control.IsFocused" Value="true"></Condition>
<Condition Property="Control.IsMouseOver" Value="true"></Condition>
</MultiTrigger.Conditions> <!--设置多个属性值-->
<MultiTrigger.Setters>
<Setter Property="Control.FontSize" Value="30"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
</Window.Resources> <StackPanel>
<!--设置样式。-->
<Button Style="{StaticResource SetButton}">Hello,World!!!</Button>
</StackPanel>
7.4、事件触发器。
普通触发器是等待属性发生变化,而事件触发器是等待特定的事件被引发。事件触发器要求用户提供一系列修改控件的动作,这些动作通常被应用为动画。
<Window.Resources>
<Style x:Key="SetButtonMouseOver">
<!--设置触发器-->
<Style.Triggers>
<!--设置触发器的路由事件-->
<EventTrigger RoutedEvent="Control.MouseEnter">
<!--设置一个动画,改变元素的字体的大小-->
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0:2" Storyboard.TargetProperty="FontSize" To="30"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources> <StackPanel>
<!--设置样式-->
<Button Style="{StaticResource SetButtonMouseOver}">Hello,World!!!</Button>
</StackPanel>
End!
WPF中样式和行为和触发器的更多相关文章
- wpf中的触发器详解
原文 http://zwkufo.blog.163.com/blog/static/25882512009724113250883/ 7.1.2 简单逻辑的表示--触发器(1) 在本章的多处介绍中都会 ...
- wpf中的触发器详解 (转自 乂乂的日志 - 网易博客)
2010-03-24 16:19:07| 分类: WPF相关 | 标签: |字号大中小 订阅 wpf中的触发器详解 WPF/C# 2009-08-24 11:32:50 7.1.2 简单 ...
- WPF中的Style(风格,样式)(转)
在WPF中我们可以使用Style来设置控件的某些属性值,并使该设置影响到指定范围内的所有该类控件或影响指定的某一控件,比如说我们想将窗口中的所有按钮都保持某一种风格,那么我们可以设置一个Style,而 ...
- WPF中的Style(风格,样式)
作者: 周银辉 来源: 博客园 发布时间: 2009-02-27 15:04 阅读: 6698 次 推荐: 0 原文链接 [收藏] 在WPF中我们可以使用Style来设置控件的某些 ...
- wpf中的样式与模板
1.WPF样式类似于Web应用程序中的CSS,在WPF中可以为控件定义统一的样式(Style).样式属于资源的一种,例如为Button定义统一的背景颜色和字体: <Window.Resource ...
- WPF 中的style 样式
WPF相较于以前学的WinForm,WPF在UI设计与动画方面的炫丽是最吸引我来学习的.在WPF中XMAL代码的引入使得代码的编写能够前后端分离,为获得更好的界面,也使得我们不得不分出一半的时间花在前 ...
- WPF中使用ValueConverter来实现“范围条件触发器”
在WPF中,我们知道界面层可以通过Trigger触发器实现“条件”——“赋值”的功能 属性触发器Property Trigger:当Dependency Property的值发生改变时触发.数据触发器 ...
- WPF中的触发器简单总结
原文 http://blog.sina.com.cn/s/blog_5f2ed5cb0100p3ab.html 触发器,从某种意义上来说它也是一种Style,因为它包含有一个Setter集合,并根据一 ...
- C#、WPF中如何自定义鼠标样式
需求:在C#中如何自定义鼠标样式?在这里可以分两种情况,一种是在winForm,另一种是在WPF中(注意使用的Cursor对象不一样) 解决办法如下: a.首先针对WinForm中,我们可以采用图标加 ...
随机推荐
- Linux系统编程_8_进程控制之fork_wait_waitpid函数
fork函数: #include <unistd.h> pid_t fork(void); fork用来创建一个子进程: 特点: fork调用后会返回两次,子进程返回0,父进 ...
- vmnet1 and vmnet8
在使用VMware Workstation创建虚拟机时.创建的虚拟机中能够包含网卡.你能够依据须要选择使用何种虚拟网卡.从而表明想要连接到那个虚拟交换机.在VMware Workstation中,默认 ...
- 图形界面Aardio
用aardio给python写个图形界面 前阵子在用python写一些小程序,写完后就开始思考怎么给python程序配一个图形界面,毕竟控制台实在太丑陋了. 于是百度了下python的图形界面库,眼花 ...
- 【hdu2457】ac自动机 + dp
传送门 题目大意: 给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串. 题解: ac自动机 + dp,用病毒串建好ac自动机,有毒的末尾flag置为true 构建fail ...
- 解决eclipse 保存卡顿的问题
开发十年,就只剩下这套Java开发体系了 >>> eclipse 如果启动慢,还可以接收. 可是如果是 保存的时候卡顿, 有时候会 卡顿 3秒-5 秒的,感觉到写代码特别的不顺畅 ...
- 【27.66%】【codeforces 592D】Super M
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- android studio 各种问题 应该能帮助到你们
1. you can import your settings from a previous version of Studio 可以导入您的设置从先前版本的工作室 2. I want to imp ...
- URAL 1577. E-mail(简单二维dp)
给你两个子串,让你找出来一个最短的字符串包括这两个子串,输出最多的子串有多少种. 类似于最长公共子序列,相等的话长度+1,不想等的话比較长度,使用长度小的. 1577. E-mail Time lim ...
- 探究Promise的实现
最终答案在一个类库里,地址 https://github.com/yahoo/ypromise 这个类库也有问题,就是下面这道面试题在IE9里实现不一致,类库里还是用了setTimeout.去年尝试用 ...
- .NET CORE的TagHelper智能提示
VisualStudio2017下ASP.NET CORE的TagHelper智能提示不能使用的解决办法 之前在VS2017RC中就发现该问题,安装了依赖,但是前段一直点不出来asp-for,后来 ...