样式资源-切换主题,动态切换字典文件

这个例子说明,多个字典文件中引用同一个资源key,可以切换文件使用不同的资源字典。

1.资源key类

using System.Windows;
namespace 动态资源_主题切换
{
    public static class ResourceKeys
    {
        // 前景色资源键(用于文本颜色)
        public static readonly ResourceKey TextForeground = new ComponentResourceKey(typeof(ResourceKeys), "TextForeground");

        // 按钮背景资源键
        public static readonly ResourceKey ButtonBackground = new ComponentResourceKey(typeof(ResourceKeys), "ButtonBackground");

        // 窗口背景资源键
        public static readonly ResourceKey WindowBackground = new ComponentResourceKey(typeof(ResourceKeys), "WindowBackground");
    }
}

2.暗色主题的字典和亮色主题的字典

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:动态资源_主题切换">
    <!-- 对应ResourceKeys.TextForeground的资源值 -->
    <SolidColorBrush x:Key="{x:Static local:ResourceKeys.TextForeground}" Color="White" />
    <!-- 对应ResourceKeys.ButtonBackground的资源值 -->
    <SolidColorBrush x:Key="{x:Static local:ResourceKeys.ButtonBackground}" Color="#2E7D32" />
    <!-- 深绿 -->
    <!-- 对应ResourceKeys.WindowBackground的资源值 -->
    <SolidColorBrush x:Key="{x:Static local:ResourceKeys.WindowBackground}" Color="#333333" />
    <!-- 深灰 -->
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:动态资源_主题切换">
    <!-- 对应ResourceKeys.TextForeground的资源值 -->
    <SolidColorBrush x:Key="{x:Static local:ResourceKeys.TextForeground}" Color="Black" />
    <!-- 对应ResourceKeys.ButtonBackground的资源值 -->
    <SolidColorBrush x:Key="{x:Static local:ResourceKeys.ButtonBackground}" Color="LightBlue" />
    <!-- 绿色 -->
    <!-- 对应ResourceKeys.WindowBackground的资源值 -->
    <SolidColorBrush x:Key="{x:Static local:ResourceKeys.WindowBackground}" Color="White" />
</ResourceDictionary>

3.合并字典,但迷人和不亮色的

<Application x:Class="动态资源_主题切换.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:动态资源_主题切换"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!-- 合并默认主题(浅色主题) -->
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="LightTheme.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

4.使用字典,并且可以切换

<Window x:Class="动态资源_主题切换.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:动态资源_主题切换"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        
    Background="{DynamicResource {x:Static local:ResourceKeys.WindowBackground}}">
    <Window.Resources>
        <Style TargetType="Button" x:Key="ThemeButtonStyle">
            <!-- 绑定按钮背景到资源键(动态更新) -->
            <Setter Property="Background" Value="{DynamicResource {x:Static local:ResourceKeys.ButtonBackground}}" />
            <!-- 绑定按钮前景色到资源键(动态更新) -->
            <Setter Property="Foreground" Value="{DynamicResource {x:Static local:ResourceKeys.TextForeground}}" />
            <Setter Property="Padding" Value="10,5" />
            <Setter Property="Margin" Value="5" />
        </Style>
    </Window.Resources>
    <StackPanel Margin="20" HorizontalAlignment="Center">
        <!-- 文本前景色绑定到资源键 -->
        <TextBlock Text="这是一段测试文本" 
                   Foreground="{DynamicResource {x:Static local:ResourceKeys.TextForeground}}"
                   FontSize="16" Margin="5" />

        <!-- 使用自定义样式的按钮 -->
        <Button Content="普通按钮" Style="{StaticResource ThemeButtonStyle}" />

        <!-- 切换主题的按钮 -->
        <Button Content="切换主题" Click="SwitchTheme_Click" Style="{StaticResource ThemeButtonStyle}" />
    </StackPanel>
</Window>

后台代码的切换逻辑,是清楚合并的字典,添加另一个样式的字典

using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 动态资源_主题切换
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private bool _isDarkTheme = false; // 标记当前是否为深色主题
        private void SwitchTheme_Click(object sender, RoutedEventArgs e)
        {
            // 清除当前应用合并的资源字典
            Application.Current.Resources.MergedDictionaries.Clear();

            // 根据当前主题切换资源
            if (_isDarkTheme)
            {
                // 切换到浅色主题
                Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
                {
                    Source = new Uri("LightTheme.xaml", UriKind.Relative)
                });
            }
            else
            {
                // 切换到深色主题
                Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
                {
                    Source = new Uri("DarkTheme.xaml", UriKind.Relative)
                });
            }

            _isDarkTheme = !_isDarkTheme; // 反转主题标记
        }
    }
}

 

posted @ 2025-10-30 19:24  灰色淡季  阅读(2)  评论(0)    收藏  举报