现在很多软件都支持一键切换主题颜色的功能,以适应不同场景下给予人不同的体验。
那WPF如何做到一键换肤呢?
一、思路
更换控件的样式资源文件。我们都知道不要写死控件的样式,例如直接按钮设置背景色为黑色
<Setter Property="Background" Value="Black"/>
大部分时候会另外新建两个字典资源文件<ResourceDictionary>
,一个Button.xaml
专门写按钮的样式资源,通过style = {StaticResource x:Key}
的方式调用。另一个是Colors.xaml
专门写各种颜色的资源文件。把这两个文件都放在Resources
目录下。如我的文件结构:
Colors.xaml
待切换的主题文件。
现在,写一个测试样例,点击上面按钮,改变下面按钮的样式(通过将Color.xaml更换成DarkColors.xaml实现)
- 布局:
<StackPanel Orientation="Vertical">
<Button Content="改变主题" Width="100" Height="50" Margin="10" Click="Button_Click"/>
<Button Content="改变主题" Width="100" Height="50" Margin="10"
Style="{StaticResource DefaultButtonStyle}"/>
</StackPanel>
- 样式:
1、在App.xaml
中添加Color.xaml
和Button.xaml
两个文件
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Learn;component/Resources/Colors.xaml"/>
<ResourceDictionary Source="pack://application:,,,/Learn;component/Resources/Button.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
2、Color.xaml
<SolidColorBrush x:Key="DefaultButtonBG" Color="AliceBlue"/>
<SolidColorBrush x:Key="DefaultButtonFG" Color="Black"/>
3、DarkColor.xaml
<SolidColorBrush x:Key="DefaultButtonBG" Color="Black"/>
<SolidColorBrush x:Key="DefaultButtonFG" Color="White"/>
4、Button.xaml
<Style x:Key="DefaultButtonStyle" TargetType="Button">
<!--注意使用DynamicResource而不是StaticResource-->
<Setter Property="Background" Value="{DynamicResource DefaultButtonBG}"/>
<Setter Property="Foreground" Value="{DynamicResource DefaultButtonFG}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
5、点击事件
private void Button_Click(object sender, RoutedEventArgs e)
{
ResourceDictionary resource = new ResourceDictionary();
if (Application.Current.Resources.MergedDictionaries[0].Source.ToString() == "pack://application:,,,/Learn;component/Resources/Colors.xaml")
{
resource.Source = new Uri("pack://application:,,,/Learn;component/Resources/DarkColors.xaml");
}
else
{
resource.Source = new Uri("pack://application:,,,/Learn;component/Resources/Colors.xaml");
}
Application.Current.Resources.MergedDictionaries[0] = resource;
}
二、效果
这只是一个演示,实际换肤,颜色资源肯定复杂的多。