原文地址:http://www.cnblogs.com/DebugLZQ/p/3181040.html 原作者:DebugLZQ
UI的风格一致性是应用程序应当关注的重要特性。
1.Creating and using styles
用一个Demo,来总结Style。
MainWindow.xaml如下:
<Window x:Class="CreatingAndUsingStyle.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Styled Calculatot" Height="269" Width="180" ResizeMode="CanMinimize"> <Window.Resources> <Style TargetType="Button" x:Key="numericStyle"> <Setter Property="FontSize" Value="20" /> <Setter Property="Margin" Value="4" /> <Setter Property="Padding" Value="6" /> <Setter Property="Effect"> <Setter.Value> <DropShadowEffect Color="Blue"/> </Setter.Value> </Setter> </Style> <Style TargetType="Button" x:Key="operatorStyle" BasedOn="{StaticResource numericStyle}"> <Setter Property="FontWeight" Value="ExtraBold" /> <Setter Property="Effect"> <Setter.Value> <DropShadowEffect Color="Red" /> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBox Background="Cyan" IsReadOnly="True" Grid.ColumnSpan="4"/> <Button Content="7" Grid.Row="1" Style="{StaticResource numericStyle}"/> <Button Content="8" Grid.Row="1" Grid.Column="1" Style="{StaticResource numericStyle}"/> <Button Content="9" Grid.Row="1" Grid.Column="2" Style="{StaticResource numericStyle}"/> <Button Content="4" Grid.Row="2" Style="{StaticResource numericStyle}"/> <Button Content="5" Grid.Row="2" Grid.Column="1" Style="{StaticResource numericStyle}"/> <Button Content="6" Grid.Row="2" Grid.Column="2" Style="{StaticResource numericStyle}"/> <Button Content="1" Grid.Row="3" Style="{StaticResource numericStyle}"/> <Button Content="2" Grid.Row="3" Grid.Column="1" Style="{StaticResource numericStyle}"/> <Button Content="3" Grid.Row="3" Grid.Column="2" Style="{StaticResource numericStyle}"/> <Button Content="0" Grid.Row="4" Style="{StaticResource numericStyle}"/> <Button Content="=" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2" Style="{StaticResource operatorStyle}"> <Button.Effect> <DropShadowEffect Color="Green" /> </Button.Effect> </Button> <Button Content="+" Grid.Row="4" Grid.Column="3" Style="{StaticResource operatorStyle}"/> <Button Content="-" Grid.Row="3" Grid.Column="3" Style="{StaticResource operatorStyle}"/> <Button Content="X" Grid.Row="2" Grid.Column="3" Style="{StaticResource operatorStyle}"/> <Button Content="/" Grid.Row="1" Grid.Column="3" Style="{StaticResource operatorStyle}"/> </Grid> </Window>
效果如下:
Point of Interest
Setter的Property必须是依赖属性;
FrameworkStyle暴露了Style这个属性;
Style一般放在Resources中.
TargetType="Button" 指定Style应用的类型。
一般,我们使用Style的时候,我们都会设置这个(In practice ,TargetType is always specified.),想想为什么?
3. x:Key="numericStyle" 可以根据需要进行有或无。
a.当其有的时候,我们需要对需要 Style="{StaticResource numericStyle}" .
b.其不设置的时候,默认所有TargetType使用此Style。 见2.
4. BasedOn="{StaticResource numericStyle}" 这是Style的继承。
Style继承时,可以修改BaseOn Style的Setter。如operatorStyle的 部分所示。
Style继承很好用,但是要注意:基Style的修改会影响子style.
5.对于应用了Style的element,我们可以设置其属性值,且这个优先级更高(覆盖Style设置)。如"="Button的 部分所示。
2.Applying a style automatically
我们移除 x:Key="numericStyle"。让所有Button使用这个style.
1.不为Style指定x:key,这个Style将应用于所有的x:Tyle element;
没有指定x:key,不代表其没有key,其key由x:Tyle定义,就本例而言是{x:Type Button}},从Style继承中(xaml中绿色高亮代码),可见一斑。
2.如果,这样的Style被Set在Window的Resource,则影响这个Window上的所有x:Type类型的element;
如果被set在application's resources,则影响所有window。
3.如果,我们希望某个element不应用这个style,我们可以设置它的Style属性为其他style;
如果想让它保持默认的样子,我们可以设置其Style="{x:Null}",如Button “0”。
3.动态更换Style
在Skin文件夹中添加两个Resource Dictionary,如下:


并设置其Property为:Content/Aways Copy.
“These settings prevent the default compilation to BAML and also provide the flexibility to
change the skins without recompilation. ”
请参考DebugLZQ前面的博文:WPF整理-二进制资源和内容
MainWindow.xaml,MainWindow.xaml.cs如下:
<Window x:Class="WPFStyleTriggerAndControlTemplate.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="303.719" Width="530.785"> <Grid Margin="0,0,2,0"> <TextBox HorizontalAlignment="Left" Height="23" Margin="10,35,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> <TextBox HorizontalAlignment="Left" Height="23" Margin="156,35,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> <TextBox HorizontalAlignment="Left" Height="23" Margin="293,35,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" RenderTransformOrigin="1.577,0.303"/> <Button Content="Button" HorizontalAlignment="Left" Margin="433,35,0,0" VerticalAlignment="Top" Width="75"/> <GroupBox FontSize="28" Header="Select Skin" Margin="75,102,62,0" VerticalAlignment="Top" Height="158"> <StackPanel Orientation="Vertical" HorizontalAlignment="Center"> <RadioButton Content="Normal" Checked="AllRadioButtonChecked"/> <RadioButton Content="Blue Skin" Checked="AllRadioButtonChecked"/> <RadioButton Content="Red Skin" Checked="AllRadioButtonChecked"/> </StackPanel> </GroupBox> </Grid> </Window>
namespace WPFStyleTriggerAndControlTemplate { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void AllRadioButtonChecked(object sender, RoutedEventArgs e) { switch (((RadioButton)sender).Content.ToString()) { case "Blue Skin": ChangeSkin("Skins/BlueSkin.xaml"); break; case "Red Skin": ChangeSkin("Skins/RedSkin.xaml"); break; case "Normal": Application.Current.Resources.MergedDictionaries.Clear(); break; } } void ChangeSkin(string skinRelativeUri) { var si = Application.GetContentStream(new Uri(skinRelativeUri, UriKind.Relative)); var rd = (ResourceDictionary)XamlReader.Load(si.Stream); Application.Current.Resources.MergedDictionaries.Clear(); Application.Current.Resources.MergedDictionaries.Add(rd); } } }
运行效果如下: