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. 最佳实践
主题资源组织
按功能分类资源
使用统一的命名规范
保持资源的一致性
性能优化
避免过多的动态资源
使用缓存机制
合理组织资源字典
扩展性考虑
支持自定义主题
提供主题切换动画
实现主题预览功能
用户体验
提供平滑的切换效果
保存用户的主题偏好
支持系统主题跟随
这种实现方式具有良好的可维护性和扩展性,同时保证了性能和用户体验