WPF的样式主题

本文详细介绍了如何在WPF应用中实现动态主题和样式切换。通过设置窗口的样式和模板,并使用动态资源,可以实现实时更新窗体的颜色和样式,达到更换主题的效果。同时,通过移除和添加资源字典,可以实现不同颜色和样式的动态切换,包括按钮、TextBlock等控件。示例代码展示了如何在按钮点击事件中切换颜色和整个资源字典,以及如何通过属性控制单色和彩色模式的切换。
摘要由CSDN通过智能技术生成

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Admini$trat0r

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值