注:一下内容及代码基本来自Charles Petzold著,蔡学庸译,电子工业出版社出版的《Windows Presentation Foundation 程序设计指南》一书
因此,最基本的Style格式是:
< Style ... >
< Setter ... />
< EventSetter ... />
< Setter ... />
</ Style >
如果是在c#代码里,需要将Properyt设置为FontSizeProperty
如果需要将Value设置为null:Value="{x:Null}"
< Button xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
HorizontalAlignment ="Center" VerticalAlignment ="Center"
Foreground ="Red" >
< Button.Style >
< Style >
< Setter Property ="Button.FontSize" Value ="18pt" />
< Setter Property="Control.Foreground" Value="Blue" />
</ Style >
</ Button.Style >
Button with Local Style
</ Button >
如下,一个由Button控件和TextBlock element共用的Style
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style x:Key ="normal" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.Foreground" Value ="Blue" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
< Setter Property ="Control.Padding" Value ="20, 10, 20, 10" />
</ Style >
</ StackPanel.Resources >
< Button Style ="{StaticResource normal}" >
Button on top of the stack
</ Button >
< TextBlock Style ="{StaticResource normal}" >
TextBlock in the middle of the stack
</ TextBlock >
< Button Style ="{StaticResource normal}" >
Button on the bottom of the stack
</ Button >
</ StackPanel >
也可以为某个独有的Property定义一个Setter。例如:
< Setter Property ="Button.IsDefault" Value ="true" />
只会设置Button的IsDefault,因为TextBlock不具有此属性
可以在多个resource中使用相同的key来定义stlye。对于某个特定的element来说,它将沿视觉树往上搜索,采用第一个和key关联的style。
< Grid xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< Grid.Resources >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.Foreground" Value ="Blue" />
</ Style >
</ Grid.Resources >
< StackPanel >
< StackPanel.Resources >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="Control.Foreground" Value ="Red" />
</ Style >
</ StackPanel.Resources >
< Button >
Button Number 1
</ Button >
< Button >
Button Number 2
</ Button >
< Button >
Button Number 3
</ Button >
</ StackPanel >
</ Grid >
说明:
这些按钮会使用在StackPanel中定义的style,前景色为红色,字体为默认值。
使用相同名称的style不会覆盖某些property的同时还去保留另外一些。
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style x:Key ="normal" >
<Style.Resources>
<LinearGradientBrush x:Key="gradbrush"
StartPoint="1,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="LightBlue" Offset="0" />
<GradientStop Color="Aquamarine" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</ Style.Resources >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
< Setter Property ="Control.Background"
Value ="{StaticResource gradbrush}" />
</ Style >
</ StackPanel.Resources >
< Button Style ="{StaticResource normal}" >
Button Number 1
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 2
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 3
</ Button >
</ StackPanel >
以上代码,如果不使用Resource,就要将value打散:
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style x:Key ="normal" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
< Setter Property ="Control.Background" >
<Setter.Value>
<LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="LightBlue" Offset="0" />
<GradientStop Color="Aquamarine" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</ Setter >
</ Style >
</ StackPanel.Resources >
< Button Style ="{StaticResource normal}" >
Button Number 1
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 2
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 3
</ Button >
</ StackPanel >
TargetType,指定此style被用到何种类型的element上。
被应用的element必须“类型完全符合”,例如,如果TargetType为Control,则此Sytle不会采用到Button或者label控件上。
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="FontSize" Value ="24" />
< Setter Property ="Foreground" Value ="Blue" />
</ Style >
< Style TargetType ="{x:Type TextBlock}" >
< Setter Property ="Foreground" Value ="Red" />
</ Style >
</ StackPanel.Resources >
<Button>
Button with Text Content
</Button >
<TextBlock>
TextBlock Text
</TextBlock >
<Button>
<TextBlock>
Button with TextBlock Content
</TextBlock>
</Button >
</ StackPanel >
说明:
第一个element:<Button>采用第一个style。前景色为蓝色,字体为24
第二个element:<TextBlock>采用第二个style。前景色为红色,字体为默认值
第三个element:<Button>中的<TextBlock>,前景色会采用第二个style(红色),而字体为24。原因是Sytle比“property继承”优先级高,所以前景色用第二个style,但是由于该style中没有对字体设定,所以会继承视觉树上其父亲的此property。
注:
BasedOn有类似“继承”的作用,可以修改已有的Style:
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style x:Key ="normal" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.Foreground" Value ="Blue" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
< Setter Property ="Control.Padding" Value ="20, 10, 20, 10" />
</ Style >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.Foreground" Value ="Blue" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
</ Style >
< Style x:Key="hotbtn"
TargetType="{x:Type Button}"
BasedOn ="{StaticResource {x:Type Button}}" >
< Setter Property ="Control.Foreground" Value ="Red" />
</ Style >
< Style x:Key="newbtn"BasedOn ="{StaticResource normal}" >
< Setter Property ="Control.Foreground" Value ="Red" />
</ Style >
</ StackPanel.Resources >
< Button Style ="{StaticResource normal}" >
Button Number 1
</ Button >
< Button Style ="{StaticResource hotbtn}" >
Button Number 2
</ Button >
< Button Style ="{StaticResource newbtn}" >
Button Number 3
</ Button >
</ StackPanel >
注:如果已有的Style既有key又有TargetType,那么baseon的style也要都指定
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style TargetType ="{x:Type Control}" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.Foreground" Value ="Blue" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
</ Style >
< Style TargetType ="{x:Type Button}"
BasedOn ="{StaticResource {x:Type Control}}" >
< Setter Property ="Control.Foreground" Value ="Red" />
</ Style >
< Style TargetType ="{x:Type Label}"
BasedOn ="{StaticResource {x:Type Control}}" >
< Setter Property ="Control.Foreground" Value ="Green" />
</ Style >
< Style TargetType ="{x:Type TextBox}"
BasedOn ="{StaticResource {x:Type Control}}" >
</ Style >
</ StackPanel.Resources >
< Button >
Button Control
</ Button >
< Label >
Label Control
</ Label >
< TextBox >
TextBox Control
</ TextBox >
</ StackPanel >
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="FontSize"
Value ="{Binding ElementName=scroll, Path=Value}" />
< Setter Property ="HorizontalAlignment" Value ="Center" />
< Setter Property ="Margin" Value ="24" />
</ Style >
</ StackPanel.Resources >
< ScrollBar Name="scroll" Orientation ="Horizontal" Margin ="24"
Minimum ="11" Maximum ="100" Value ="24" />
< Button >
Button Number 1
</ Button >
< Button >
Button Number 2
</ Button >
< Button >
Button Number 3
</ Button >
</ StackPanel >
以上Button的Fontsize的Value被绑定到一个名为“scroll”的ScrollBar的Value Property上。
< Setter Property ="X2"
Value ="{Binding RelativeSource={RelativeSource self},
Path=X1}" />
以上代码将x2属性的值绑定为和x1一样。
EventerSetter和Setter级别相同,用来为特定的routed事件设定事件处理函数
< Window.Resources >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="FontSize" Value ="24" />
< Setter Property ="HorizontalAlignment" Value ="Center" />
< Setter Property ="Margin" Value ="24" />
<EventSetter Event="Click" Handler="ButtonOnClick" />
</ Style >
</ Window.Resources >
< StackPanel >
< Button >
Button Number 1
</ Button >
< Button >
Button Number 2
</ Button >
< Button >
Button Number 3
</ Button >
</ StackPanel >
</ Window >
一下依次介绍除EventTrigger之外的各种Trigger
Trigger是最常见的,用来指定control或element应该如何响应特定的propertyd的改变,这些property常常都涉及到用户的输入,例如IsMouseOver property
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style x:Key ="normal" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
< Style.Triggers >
< Trigger Property="Control.IsMouseOver" Value="true">
<Setter Property="Control.FontStyle" Value="Italic" />
<Setter Property="Control.Foreground" Value="Blue" />
</Trigger >
< Trigger Property="Button.IsPressed" Value="true">
<Setter Property="Control.Foreground" Value="Red" />
</Trigger >
</Style.Triggers >
</ Style >
</ StackPanel.Resources >
< Button Style ="{StaticResource normal}" >
Button Number 1
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 2
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 3
</ Button >
</ StackPanel >
说明:
1. 当property的值被改变回去时,被Trigger修改的Property也会恢复他们原始的状态
2. 以上两个Trigger的次序对效果有所影响,如果两个Trigger对相同的property做设定,后一个会覆盖前一个。如果以上两个Trigger对调,文字不会变成红色,因为press的时候,IsMouseOver肯定是为True的。
MultiTrigger只有在两个或者多个事件都成立时才会被触发
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style x:Key ="normal" >
< Setter Property ="Control.FontSize" Value ="24" />
< Setter Property ="Control.HorizontalAlignment" Value ="Center" />
< Setter Property ="Control.Margin" Value ="24" />
< Style.Triggers >
< Trigger Property ="Button.IsPressed" Value ="True" >
< Setter Property ="Control.Foreground" Value ="Red" />
</ Trigger >
< MultiTrigger >
<MultiTrigger.Conditions >
<Condition Property="Control.IsMouseOver" Value="True" />
<Condition Property="Button.IsPressed" Value="False" />
</MultiTrigger.Conditions >
<Setter Property="Control.FontStyle" Value="Italic" />
<Setter Property="Control.Foreground" Value="Blue" />
</ MultiTrigger >
</ Style.Triggers >
</ Style >
</ StackPanel.Resources >
< Button Style ="{StaticResource normal}" >
Button Number 1
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 2
</ Button >
< Button Style ="{StaticResource normal}" >
Button Number 3
</ Button >
</ StackPanel >
鼠标移动到按钮上:文字蓝色
点击按钮:文字红色
鼠标移动到按钮上方且按钮没有被按下:文字斜体
DataTrigger与Trigger类似,只是用Binding取代了Property,Binding通常引用到另一个element。
< StackPanel xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< StackPanel.Resources >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="FontSize" Value ="24" />
< Setter Property ="HorizontalAlignment" Value ="Center" />
< Setter Property ="Margin" Value ="24" />
< Style.Triggers >
< DataTrigger Binding ="{Binding ElementName=txtbox,
Path=Text.Length}"
Value ="0" >
< Setter Property="IsEnabled" Value="False" />
</DataTrigger >
</ Style.Triggers >
</ Style >
</ StackPanel.Resources >
< TextBox Name ="txtbox" HorizontalAlignment ="Center"
Width ="2in" Margin ="24" />
< Button >
Button Number 1
</ Button >
< Button >
Button Number 2
</ Button >
< Button >
Button Number 3
</ Button >
</ StackPanel >
以上设定,只有当TextBox中的字符数不为0,Button才会Enable
只有在多个绑定条件都成立时,才会触发事件
< StackPanel.Resources >
< Style TargetType ="{x:Type CheckBox}" >
< Setter Property ="HorizontalAlignment" Value ="Center" />
< Setter Property ="Margin" Value ="12" />
</ Style >
< Style TargetType ="{x:Type Button}" >
< Setter Property ="FontSize" Value ="24" />
< Setter Property ="HorizontalAlignment" Value ="Center" />
< Setter Property ="Margin" Value ="12" />
< Setter Property ="IsEnabled" Value ="False" />
< Style.Triggers >
<MultiDataTrigger>
< MultiDataTrigger.Conditions >
<Condition Binding="{Binding ElementName=chkbox1,
Path=IsChecked}"
Value="True" />
<Condition Binding="{Binding ElementName=chkbox2,
Path=IsChecked}"
Value="True" />
</ MultiDataTrigger.Conditions >
< Setter Property="IsEnabled" Value="True" />
</MultiDataTrigger >
</ Style.Triggers >
</ Style >
</ StackPanel.Resources >
< CheckBox Name ="chkbox1" >
Check 1
</ CheckBox >
< CheckBox Name ="chkbox2" >
Check 2
</ CheckBox >
< Button >
Button Number 1
</ Button >
< Button >
Button Number 2
</ Button >
< Button >
Button Number 3
</ Button >
</ StackPanel >
以上设定,只有两个checkbox都被选中,才会时按钮enable