WPF 主题切换实现思路

1. 资源字典方式

1.1 创建主题资源字典

LightTheme.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="PrimaryBackground" Color="#FFFFFF"/>
    <SolidColorBrush x:Key="PrimaryForeground" Color="#000000"/>
    <!-- 其他主题资源 -->
</ResourceDictionary>

DarkTheme.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="PrimaryBackground" Color="#1E1E1E"/>
    <SolidColorBrush x:Key="PrimaryForeground" Color="#FFFFFF"/>
    <!-- 其他主题资源 -->
</ResourceDictionary>

1.2 在 App.xaml 中引用

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Themes/LightTheme.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

1.3 主题管理器

public class ThemeManager : INotifyPropertyChanged
{
    private static ThemeManager _instance;
    public static ThemeManager Instance => _instance ??= new ThemeManager();

    public void SwitchTheme(string themeName)
    {
        var app = Application.Current;
        var mergedDicts = app.Resources.MergedDictionaries;
        
        // 清除当前主题
        mergedDicts.Clear();
        
        // 加载新主题
        var newTheme = new ResourceDictionary
        {
            Source = new Uri($"Themes/{themeName}Theme.xaml", UriKind.Relative)
        };
        mergedDicts.Add(newTheme);
    }
}

2. 动态资源绑定

2.1 在控件中使用主题资源

<Button Background="{DynamicResource PrimaryBackground}"
        Foreground="{DynamicResource PrimaryForeground}"/>

2.2 ViewModel 中实现主题切换

public class MainViewModel : BaseViewModel
{
    private ICommand _switchThemeCommand;
    public ICommand SwitchThemeCommand => _switchThemeCommand ??= new RelayCommand(ExecuteSwitchTheme);

    private void ExecuteSwitchTheme(object parameter)
    {
        string themeName = parameter as string;
        ThemeManager.Instance.SwitchTheme(themeName);
    }
}

3. 主题持久化

3.1 保存主题设置

public class ThemeSettings
{
    private const string ThemeKey = "CurrentTheme";
    
    public static void SaveTheme(string themeName)
    {
        Properties.Settings.Default.Theme = themeName;
        Properties.Settings.Default.Save();
    }
    
    public static string LoadTheme()
    {
        return Properties.Settings.Default.Theme ?? "Light";
    }
}

3.2 应用启动时加载主题

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    
    // 加载保存的主题
    string savedTheme = ThemeSettings.LoadTheme();
    ThemeManager.Instance.SwitchTheme(savedTheme);
}

4. 最佳实践

主题资源组织

按功能分类资源
使用统一的命名规范
保持资源的一致性

性能优化

避免过多的动态资源
使用缓存机制
合理组织资源字典

扩展性考虑

支持自定义主题
提供主题切换动画
实现主题预览功能

用户体验

提供平滑的切换效果
保存用户的主题偏好
支持系统主题跟随

这种实现方式具有良好的可维护性和扩展性,同时保证了性能和用户体验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值