Avalonia 11中动态变更主题和颜色的方法
首先添加一个这个工具类:
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Styling; using Avalonia.Themes.Fluent; using Avalonia.Themes.Simple; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AvaloniaChangeTheme.Views { public enum ThemeType { Fluent, Simple } public static class AppThemeUtils { private static readonly Styles _themeStylesContainer = new(); private static FluentTheme _fluentTheme; private static SimpleTheme _simpleTheme; private static IStyle _colorPickerFluent, _colorPickerSimple; private static IStyle _dataGridFluent, _dataGridSimple; public static void BeforeInitialize() { App.Current.Styles.Add(_themeStylesContainer); } public static void AfterInitialize() { _fluentTheme = (FluentTheme)App.Current.Resources["FluentTheme"]!; _simpleTheme = (SimpleTheme)App.Current.Resources["SimpleTheme"]!; _colorPickerFluent = (IStyle)App.Current.Resources["ColorPickerFluent"]!; _colorPickerSimple = (IStyle)App.Current.Resources["ColorPickerSimple"]!; _dataGridFluent = (IStyle)App.Current.Resources["DataGridFluent"]!; _dataGridSimple = (IStyle)App.Current.Resources["DataGridSimple"]!; SetTheme(ThemeType.Fluent); } private static ThemeType _prevTheme; public static ThemeType CurrentTheme => _prevTheme; public static void SetTheme(ThemeType theme) { var app = (App)App.Current!; var prevTheme = _prevTheme; _prevTheme = theme; var shouldReopenWindow = prevTheme != theme; if (_themeStylesContainer.Count == 0) { _themeStylesContainer.Add(new Style()); _themeStylesContainer.Add(new Style()); _themeStylesContainer.Add(new Style()); } if (theme == ThemeType.Fluent) { _themeStylesContainer[0] = _fluentTheme!; _themeStylesContainer[1] = _colorPickerFluent!; _themeStylesContainer[2] = _dataGridFluent!; } else if (theme == ThemeType.Simple) { _themeStylesContainer[0] = _simpleTheme!; _themeStylesContainer[1] = _colorPickerSimple!; _themeStylesContainer[2] = _dataGridSimple!; } if (shouldReopenWindow) { if (app.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime) { var oldWindow = desktopLifetime.MainWindow; var newWindow = new MainWindow(); desktopLifetime.MainWindow = newWindow; newWindow.Show(); oldWindow?.Close(); } else if (app.ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime) { singleViewLifetime.MainView = new MainView(); } } } } }
在App.xaml中,将原来的这一段删掉,因为会在代码中创建:
<Application.Styles> <FluentTheme/> </Application.Styles>
添加下面的内容:
<Application.Resources> <ResourceDictionary> <!-- Resources used only in the control catalog --> <ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Default"> <Color x:Key="CatalogBaseLowColor">#33000000</Color> <Color x:Key="CatalogBaseMediumColor">#99000000</Color> <Color x:Key="CatalogChromeMediumColor">#FFE6E6E6</Color> <Color x:Key="CatalogBaseHighColor">#FF000000</Color> </ResourceDictionary> <ResourceDictionary x:Key="Dark"> <Color x:Key="CatalogBaseLowColor">#33FFFFFF</Color> <Color x:Key="CatalogBaseMediumColor">#99FFFFFF</Color> <Color x:Key="CatalogChromeMediumColor">#FF1F1F1F</Color> <Color x:Key="CatalogBaseHighColor">#FFFFFFFF</Color> </ResourceDictionary> </ResourceDictionary.ThemeDictionaries> <!-- Styles attached dynamically depending on current theme (simple or fluent) --> <FluentTheme x:Key="FluentTheme"> </FluentTheme> <SimpleTheme x:Key="SimpleTheme" /> <StyleInclude x:Key="DataGridFluent" Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" /> <StyleInclude x:Key="DataGridSimple" Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml" /> <StyleInclude x:Key="ColorPickerFluent" Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml" /> <StyleInclude x:Key="ColorPickerSimple" Source="avares://Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml" /> </ResourceDictionary> </Application.Resources>
完整示例可以看这里:
https://github.com/bodong1987/AvaloniaSamples/tree/main/AvaloniaChangeTheme