WPF相较于以前学的WinForm,WPF在UI设计与动画方面的炫丽是最吸引我来学习的。在WPF中XMAL代码的引入使得代码的编写能够前后端分离,为获得更好的界面,也使得我们不得不分出一半的时间花在前端代码的编写上(虽然微软提供了Blend for Visual Studio这样的设计软件,但我认为学习的时候就应该从难处学),而样式(Style)又是前端代码中非常重要的元素,所以在啃《WPF编程宝典第四版》的时候边看边练习后,决定写一些学习笔记,后面也会继续写。介于内容并不深入,所以且称为入门吧。
WPF的样式是非常强大的,除了与HTML标记中的CSS类似,它还能够支持触发器(Trigger),比如当元素属性发生变化时,可通过触发器改变控件样式,但本文中暂不涉及触发器(下一篇博客里写)。先展示一个最直观的例子。
<Window x:Class="StyleTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StyleTest"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
<Window.Resources>
<FontFamily x:Key="ButtonFontFamily">Times New RomanFontFamily>
<sys:Double x:Key="ButtonFontSize">18sys:Double>
<FontWeight x:Key="ButtonFontWeight">BoldFontWeight>
Window.Resources>
<StackPanel VerticalAlignment="Center">
<Button Name="cmd" Content="Resource Button"
Width="150" Height="30" Margin="3"
FontFamily="{StaticResource ButtonFontFamily}"
FontSize="{StaticResource ButtonFontSize}"
FontWeight="{StaticResource ButtonFontWeight}"/>
StackPanel>
Window>
我们发现上面那个例子中的使用方法显得极其冗杂,还没有原来不使用资源时简明,所以我们稍加改进。
<Style x:Key="BigFontButtonStyle">
<Setter Property="Control.FontFamily" Value="Times New Roman"/>
<Setter Property="Control.FontSize" Value="18"/>
<Setter Property="Control.FontWeight" Value="Bold"/>
Style>
"Center">
<Button Name="cmd" Content="Resource Button"
Width="150" Height="30" Margin="3"
Style="{StaticResource BigFontButtonStyle}"/>
后台代码设置样式
cmd.Style = (Style)cmd.FindResource("BigFontButtonStyle");
<Style x:Key="BigFontButtonStyle" TargetType="Button">
<Setter Property="Control.FontFamily" Value="Times New Roman"/>
<Setter Property="Control.FontSize" Value="18"/>
<Setter Property="Control.FontWeight" Value="Bold"/>
Style>
只允许Button控件进行引用该样式。
光看标题有点懵逼的感觉,这个时候思考下面例子就清楚了:如何使鼠标悬浮在一行文字上时,文字高亮显示;离开时,文字恢复原样?最简单的便是通过编写控件的事件处理程序来实现。同样,我们还可以通过样式来进行实现,实现方法就是通过创建Style的EventSetter对象的集合。
<Style x:Key="MouseOverHighlightStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="Padding" Value="5"/>
"TextBlock.MouseEnter" Handler="element_MouseEnter"/>
"TextBlock.MouseLeave" Handler="element_MouseLeave"/>
Style>
"Center">
Text="This is a TextBlock"
Style="{StaticResource MouseOverHighlightStyle}"/>
后台代码:
private void element_MouseEnter(object sender,MouseEventArgs e)
{
((TextBlock)sender).Background = new SolidColorBrush(Colors.Aqua);
}
private void element_MouseLeave(object sender, MouseEventArgs e)
{
((TextBlock)sender).Background = null;
}
有时候我们希望在另一个样式的基础上创建样式,这时可通过为样式设置BasedOn特性来使用此类样式继承,使用起来非常简单。
<Style x:Key="MouseOverHighlightStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="Padding" Value="5"/>
"TextBlock.MouseEnter" Handler="element_MouseEnter"/>
"TextBlock.MouseLeave" Handler="element_MouseLeave"/>
Style>
<Style x:Key="BaseOnStyle"
TargetType="TextBlock"
BasedOn="{StaticResource MouseOverHighlightStyle}">
<Setter Property="Control.Foreground" Value="Red"/>
Style>
"Center">
Text="This is a TextBlock"
Style="{StaticResource MouseOverHighlightStyle}"/>
Text="Inherited Style TextBlock"
Style="{StaticResource BaseOnStyle}"/>
听名字依旧有些懵逼的感觉,那么继续来想一个例子:当我们需要为界面的所有Button设置统一样式的时候怎么做?当Button比较少的时候,我们可以用上面的方法逐个设置样式,但是当Button非常多的时候,这样的方法就显得麻烦了。这个时候我们就可以使用TargetType来自动的为对应的控件应用样式。直接看例子:
<Style x:Key="MouseOverHighlightStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="Padding" Value="5"/>
"TextBlock.MouseEnter" Handler="element_MouseEnter"/>
"TextBlock.MouseLeave" Handler="element_MouseLeave"/>
Style>
<Style TargetType="TextBlock"
BasedOn="{StaticResource MouseOverHighlightStyle}">
<Setter Property="Control.Foreground" Value="Green"/>
Style>
"Center">
Text="This is a TextBlock"
Style="{StaticResource MouseOverHighlightStyle}"/>
Text="Inherited Style TextBlock"
Style="{StaticResource BaseOnStyle}"/>
Text="Global Style TextBlock"/>
Text="Global Without Style TextBlock"
Style="{x:Null}"/>
x:Key="{x:Type TextBlock}"
通过这几个例子,我自己已经能够对样式有一定里理解了,但还只是入门了,后面样式的触发器才更难一些,并且具有更丰富的功能。用上了新的编辑器(markDown)感觉还是非常棒的~