原文:
PS:现在我的完工了,进入内测阶段了,终于可以腾出手来写写教程了哈,关于MailMail的介绍及内测程序索取:
欢迎帮我捉虫,以及与我交流WPF技术
WPF的样式的继承属性极少被文章提及,以至于我在编写期间为此踌躇数日,最后终于在E文版的MS社区得到指点才得以解惑。
现将其分享出来,这是一个非常有用的特性,这是所有教程在讲Style时就该顺带讲出来的,我希望更多人看到,以少走弯路。
WPF的样式需要显示声明继承,即使用Style的BasedOn属性。
我们先在资源中定义一个基样式:
< Style x:Key ="BASE" > < Setter Property ="Control.Margin" Value ="6" /> < Setter Property ="Control.Background" > < Setter.Value > < LinearGradientBrush StartPoint ="0.5,0" EndPoint ="0.5,1" > < GradientStop Offset ="1" Color ="#FF7A0000" /> < GradientStop Offset ="0.5" Color ="#FFFF0000" /> < GradientStop Offset ="0.5" Color ="#FFD40000" /> < GradientStop Offset ="0" Color ="#FFFFC5C5" /> </ LinearGradientBrush > </ Setter.Value > </ Setter > </ Style >
注意它设置属性时都是采用“Control.”前缀,因为我们没有为之确定TargetType,如果不使用这个前缀将会报错。
然后我们定义两个继承自它的样式,分别为对应按钮和文本框的样式:
< Style BasedOn =" {StaticResource BASE} " TargetType ="Button" > < Setter Property ="Foreground" Value ="#FFFFFB92" /> < Setter Property ="Padding" Value ="8,3" /> </ Style > < Style BasedOn =" {StaticResource BASE} " TargetType ="TextBox" > < Setter Property ="Foreground" Value ="#FFFFFFFF" /> </ Style >
BasedOn属性设为了我们先前设置的“BASE”,各自追加了一些属性的设置。
现在在界面上添加一个按钮和一个文本框控件:
< DockPanel Width ="225" Height ="256" > < Button DockPanel.Dock ="Bottom" > Button </ Button > < TextBox AcceptsReturn ="True" DockPanel.Dock ="Top" VerticalScrollBarVisibility ="Visible" > TextBox Test Test Test Test Test </ TextBox > </ DockPanel >
现在界面效果如下:
可以看到,按钮和文本框都继承了基样式中的背景和外边距。
此外,还可以使用BasedOn来继承现有样式。
这里的现有样式不是指WPF自带的主题基础样式,而是控件当前的样式,就是你上面看到的样式,我们下面将继承于当前的按钮样式,再进行一些改变。
在资源中新增:
< Style x:Key ="NewButton" BasedOn =" {StaticResource {x:Type Button}} " TargetType ="Button" > < Setter Property ="FontWeight" Value ="Bold" /> < Setter Property ="FontSize" Value ="22" /> < Setter Property ="BorderBrush" > < Setter.Value > < LinearGradientBrush StartPoint ="0,0" EndPoint ="0,1" > < GradientStop Offset ="0" Color ="#FFFF7300" /> < GradientStop Offset ="1" Color ="#03FF0000" /> </ LinearGradientBrush > </ Setter.Value > </ Setter > </ Style >
BasedOn属性设为了按钮类型,在样式中改变了字体的尺寸和粗细以及按钮边框的颜色。
添加一个新按钮,应用这个样式:
< Button DockPanel.Dock ="Bottom" Style =" {StaticResource NewButton} " > NewButton </ Button >
现在的界面效果:
继承现有效果有什么意义?
比如我们引用了一个外来的整套界面样式,但在局部界面上需要修改一下,这时如果新设一个样式将会是大费周折的事,直接修改控件自身的属性又会造成冗余和不一致性,继承就是最佳的选择了。
通过继承基样式及充分地重用通用资源(如色彩、笔刷),我们不难实现界面的色彩风格切换功能。
为一套样式定义多种风格供选,或是让用户自由定制他们喜欢的色彩主题,将是一项激动人心的功能。
完整代码:
Code <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Page.Resources> <Style x:Key="BASE"> <Setter Property="Control.Margin" Value="6"/> <Setter Property="Control.Background"> <Setter.Value> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Offset="1" Color="#FF7A0000"/> <GradientStop Offset="0.5" Color="#FFFF0000"/> <GradientStop Offset="0.5" Color="#FFD40000"/> <GradientStop Offset="0" Color="#FFFFC5C5"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> <Style BasedOn="{StaticResource BASE}" TargetType="Button"> <Setter Property="Foreground" Value="#FFFFFB92"/> <Setter Property="Padding" Value="8,3"/> </Style> <Style BasedOn="{StaticResource BASE}" TargetType="TextBox"> <Setter Property="Foreground" Value="#FFFFFFFF"/> </Style> <Style x:Key="NewButton" BasedOn="{StaticResource {x:Type Button}}" TargetType="Button"> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="FontSize" Value="22"/> <Setter Property="BorderBrush"> <Setter.Value> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="#FFFF7300"/> <GradientStop Offset="1" Color="#03FF0000"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </Page.Resources> <Grid> <DockPanel Width="225" Height="256"> <Button DockPanel.Dock="Bottom">Button </Button> <Button DockPanel.Dock="Bottom" Style="{StaticResource NewButton}">NewButton </Button> <TextBox AcceptsReturn="True" DockPanel.Dock="Top" VerticalScrollBarVisibility="Visible">TextBox Test Test Test Test Test </TextBox> </DockPanel> </Grid></Page>
尽管有严重的火星嫌疑...
没关系,重在分享,不怕丢龈~:
我还是要顺路推荐一下这款XAML编辑器——Kaxaml:
实在太好用了,比微软那个XamlPad强老了,一定要普及到人手一份才对。