WPF的样式
窗体的样式就是每个控件Style属性,可以使静态资源也可以是动态资源,给窗体的所有控件都设置一个样式,就做到了换主题的功能,此处的所有灵感以及代码均来自引用处的两篇博文。
主窗体
主窗体界面,此处的第二个样例ThemeWindow使用的Converter,此处不作详细介绍。
切换窗体单个颜色
SliderColorwindow给窗体设置主题颜色的样子,代码完全复制粘贴,此处可以略过直接看引用两篇文章。
首先需要把资源样式引用到App.xaml中,然后把窗体的样式设置为对应的keyStyle="{StaticResource window}"
,然后可以引用动态资源{DynamicResource color}"
,实时的更新窗体样式。
把此处为App.xaml处代码
<Application.Resources>
<ResourceDictionary>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" x:Key="color">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Orange" Offset="0.5" />
<GradientStop Color="Red" Offset="1" />
</LinearGradientBrush>
<Style x:Key="window" TargetType="Window">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="AllowsTransparency" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Border BorderBrush="{DynamicResource color}" BorderThickness="3" CornerRadius="5" Padding="4">
<Border BorderBrush="{DynamicResource color}" BorderThickness="3" CornerRadius="5" Background="{DynamicResource color}">
<Border BorderBrush="#1000" BorderThickness="3" CornerRadius="5" Padding="6">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#3FFF" Offset="0.5" />
<GradientStop Color="#1666" Offset="0.5" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter />
</Border>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
按钮点击事件内把本窗体的动态资源颜色移除,然后将新的颜色赋值。
var solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)sliderA.Value, (byte)sliderR.Value, (byte)sliderG.Value, (byte)sliderB.Value));
this.Resources.Remove("color");
this.Resources.Add("color", solidColorBrush);
原来的样子,默认使用定义好的
根据滚动条设置完主题之后
动态切换样式
ThemeResourceWindow是动态切换样式,本处参照引用的文章,先看引用文章效果更好,此时是把所有资源字典移除,如有特殊需求可以做判断等,这里的资源字典是本窗体的资源字典。
此处拿TextBlock做例子,动态资源引用textBlock,此处需要在App.xaml中添加该资源列字典,否则预览时会默认,如果是Path的背景颜色则显示null没有颜色。
<TextBlock Style="{DynamicResource textBlock}" Text="test" Width="30" Height="20"/>
对应的蓝色资源字典内容,其他资源字典只是颜色不同。
<Style x:Key="textBlock" TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue"/>
</Style>
此处是App.xaml文件代码,需要将资源字典加进来。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/DictionaryBlueTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
按钮点击事件,切换样式。
<Button Click="DictionaryThemeButton_Click" Tag=".\Resources\DictionaryRedTheme.xaml" Background="Red" Width="180" Height="100"/>
<Button Click="DictionaryThemeButton_Click" Tag=".\Resources\DictionaryGreenTheme.xaml" Background="Green" Margin="100,0" Width="180" Height="100"/>
<Button Click="DictionaryThemeButton_Click" Tag=".\Resources\DictionaryBlueTheme.xaml" Background="Blue" Width="180" Height="100"/>
点击事件代码实现,移除所有资源字典并加入新的资源字典。
if (sender is Button button)
{
var tag = button.Tag.ToString();
Uri skinDictUri = new Uri(tag, UriKind.Relative);
ResourceDictionary skinDict = Application.LoadComponent(skinDictUri) as ResourceDictionary;
Collection<ResourceDictionary> mergedDicts = Resources.MergedDictionaries;
if (mergedDicts.Count > 0)
mergedDicts.Clear();
mergedDicts.Add(skinDict);
}
窗体默认打开样式,因为在App.xaml中加入了蓝色样式。
如果什么都不加显示样式
当点击红色按钮式显示样式
动态换主题样式
ThemeTestWindows是将前面的按钮以及内容组合,也是知识点的集合,此处就是一个ToggleButton来切换按钮内Path颜色的变化。
定义一个属性来实现切换单色和彩色模式,此时只需要在窗体加载时设置它的值就可以,也可以在运行时不断切换这个值做到动态切换样式。
/// <summary>
/// 主题资源字典路径字符串
/// </summary>
public string resourceDictionaryStr;
private bool isMonochrome;
/// <summary>
/// 当前主题是否是单色模式(true单色,false彩色)
/// </summary>
public bool IsMonochrome
{
get => isMonochrome;
set
{
resourceDictionaryStr = value ? @".\Resources\MonochromeDictionary.xaml" : @".\Resources\ColorDictionary.xaml";
ToggleTheme();
isMonochrome = value;
}
}
此处是切换主题的实现和切换按钮的点击事件。
/// <summary>
/// 切换主题
/// </summary>
private void ToggleTheme()
{
Uri resourceDictionaryUri = new Uri(resourceDictionaryStr, UriKind.Relative);
ResourceDictionary resourceDictionary = Application.LoadComponent(resourceDictionaryUri) as ResourceDictionary;
Collection<ResourceDictionary> mergedDictionaries = Resources.MergedDictionaries;
if (mergedDictionaries.Count > 0)
mergedDictionaries.Clear();
mergedDictionaries.Add(resourceDictionary);
}
private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
IsMonochrome = !IsMonochrome;
toggleButton.Content = IsMonochrome ? "单色" : "彩色";
}
此处是单色样式。
点击后变彩色。
引用
https://www.cnblogs.com/SkyD/archive/2008/09/02/1281975.html#4988102
https://www.cnblogs.com/zhouyinhui/archive/2007/08/02/840326.html#4988103