WPF中的各类控件元素,都可以自由的设置其样式。诸如:
- 字体(FontFamily)
- 字体大小(FontSize)
- 背景颜色(Background)
- 字体颜色(Foreground)
- 边距(Margin)
- 水平位置(HorizontalAlignment)
- 垂直位置(VerticalAlignment)等等。
而样式则是组织和重用以上的重要工具。不是使用重复的标记填充XAML,通过Styles
创建一系列封装所有这些细节的样式。然后通过Style
属性应用封装好的样式。这点类似于CSS样式。然而,WPF样式的功能更加强大,如控件的行为。WPF的样式还支持触发器。
示例
为了能够直观了解到样式(Style)的使用方法,下面演示一个从传统的定义控件样式到使用Style组织样式的方法。
下面的例子中,给4个TextBlock设置同样的样式:字体、字体大小、字体颜色、加粗设置。
效果图与实际代码如下所示:
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Text1" FontFamily="宋体" FontSize="18" Foreground="Red" FontWeight="Bold"/>
<TextBlock Text="Text1" FontFamily="宋体" FontSize="18" Foreground="Red" FontWeight="Bold"/>
<TextBlock Text="Text1" FontFamily="宋体" FontSize="18" Foreground="Red" FontWeight="Bold"/>
<TextBlock Text="Text1" FontFamily="宋体" FontSize="18" Foreground="Red" FontWeight="Bold"/>
</StackPanel>
上面有讲到,样式是组织和重用的工具。而上面的代码,由于每个元素都是相同的,但是每个元素XAML都重复定义。下面将介绍通过样式如何优化上面的代码。
- 第一步:在
Resources
目录下定义一个TextBlockStyle
的样式,完整代码如下:
Style
结构定义了一个x:key
这点类似于html中定义id
和class
,然后CSS即可对相应的class
和id
样式生效。
TargetType
的设置为类型TextBlock
,设置目标类型静态文本TextBlock
。
- 第二步:通过控件的
Style
属性来引用x:key
的样式,代码如下:
注意:当控件引用了某个样式,在控件本身并没有定义该属性的情况下,优先使用样式中的定义,否则优先控件本身的定义。如下所示,样式中设置了颜色为Red
,但是控件本身又设置了Green
,那么控件的最终效果就是Green
。
触发器介绍
顾名思义,触发器可以理解为,当达到了触发的条件,那么执行预期内的响应,可以是样式、数据变化、动画等。
触发器通过
Style.Triggers
集合连接到样式中,每个样式都可以有任意多个触发器,并且每个触发器都是System.Windows.TriggersBase
的派生类实例,以下是触发器的类型:
- Trigger:监测依赖属性的变化、触发器生效。
- MultiTrigger:通过多个条件的设置、达到满足条件、触发器生效
- DataTrigger:通过数据的变化、触发器生效。
- MultiDataTrigger:多个数据变化的触发器。
- EventTrigger:事件触发器,触发了某类事件时,触发器生效。
Trigger
下面以
Border
为例,演示一个简单的Trigger
触发器。当鼠标进入
Border
的范围,改变Border
的背景颜色和边框颜色,当鼠标离开Border
的范围,还原Border
的颜色。代码如下所示:
实际效果:
MultiTrigger
和
Trigger
类似,MultiTrigger可以设置多个条件满足时,触发,下面以TextBox
为例,做一个简单的Demo。当鼠标进入文本框的范围,并且光标设置到
TextBox
上,则把TextBox
的背景颜色改变成Red。
实际效果:
EventTrigger
事件触发器,当触发了某类事件,触发器执行响应。
下面用实例演示,为了能直观感受到这类触发器的作用,用动画演示其功能,下面使用了动画相关的知识,在学习到后面几个章节,读者可以进行相关的内容学习。
当鼠标进入按钮的范围中,在0.02秒内,把按钮的字体变成18号。
当鼠标离开按钮的范围时,在0.02秒内,把按钮的字体变成13号。代码及效果如下:
对于DataTrigger / MultiDataTrigger
的功能类似,只不过触发条件变成了以数据的方式为条件,需要的自己了解。