WPF style 换肤

原文地址: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,如下:

View Code
View Code

并设置其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);
        }

    }
}
复制代码

运行效果如下:


原文地址:https://www.cnblogs.com/kevinWu7/p/10163536.html