diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index 36b6fc2dcd..aba22a4af6 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -5,6 +5,7 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml.Styling; using Avalonia.Styling; +using Avalonia.Themes.Fluent; using ControlCatalog.ViewModels; namespace ControlCatalog @@ -16,33 +17,17 @@ namespace ControlCatalog DataContext = new ApplicationViewModel(); } - private static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) + public static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) { Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml") }; - private static readonly StyleInclude DataGridDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) + public static readonly StyleInclude DataGridDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) { Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Default.xaml") }; - public static Styles FluentDark = new Styles - { - new StyleInclude(new Uri("avares://ControlCatalog/Styles")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/FluentDark.xaml") - }, - DataGridFluent - }; - - public static Styles FluentLight = new Styles - { - new StyleInclude(new Uri("avares://ControlCatalog/Styles")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/FluentLight.xaml") - }, - DataGridFluent - }; + public static FluentTheme Fluent = new FluentTheme(new Uri("avares://ControlCatalog/Styles")); public static Styles DefaultLight = new Styles { @@ -65,8 +50,7 @@ namespace ControlCatalog new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) { Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml") - }, - DataGridDefault + } }; public static Styles DefaultDark = new Styles @@ -90,14 +74,13 @@ namespace ControlCatalog new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) { Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml") - }, - DataGridDefault + } }; public override void Initialize() { - Styles.Insert(0, FluentLight); - + Styles.Insert(0, Fluent); + Styles.Insert(1, DataGridFluent); AvaloniaXamlLoader.Load(this); } diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs index abedda3c85..0579355831 100644 --- a/samples/ControlCatalog/MainView.xaml.cs +++ b/samples/ControlCatalog/MainView.xaml.cs @@ -3,14 +3,12 @@ using System.Collections; using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; -using Avalonia.Markup.Xaml.MarkupExtensions; -using Avalonia.Markup.Xaml.Styling; -using Avalonia.Markup.Xaml.XamlIl; using Avalonia.Media; using Avalonia.Media.Immutable; using Avalonia.Platform; -using ControlCatalog.Pages; +using Avalonia.Themes.Fluent; using ControlCatalog.Models; +using ControlCatalog.Pages; namespace ControlCatalog { @@ -43,14 +41,36 @@ namespace ControlCatalog { if (themes.SelectedItem is CatalogTheme theme) { - Application.Current.Styles[0] = theme switch + var themeStyle = Application.Current.Styles[0]; + if (theme == CatalogTheme.FluentLight) + { + if (App.Fluent.Mode != FluentThemeMode.Light) + { + App.Fluent.Mode = FluentThemeMode.Light; + } + Application.Current.Styles[0] = App.Fluent; + Application.Current.Styles[1] = App.DataGridFluent; + } + else if (theme == CatalogTheme.FluentDark) + { + + if (App.Fluent.Mode != FluentThemeMode.Dark) + { + App.Fluent.Mode = FluentThemeMode.Dark; + } + Application.Current.Styles[0] = App.Fluent; + Application.Current.Styles[1] = App.DataGridFluent; + } + else if (theme == CatalogTheme.DefaultLight) + { + Application.Current.Styles[0] = App.DefaultLight; + Application.Current.Styles[1] = App.DataGridDefault; + } + else if (theme == CatalogTheme.DefaultDark) { - CatalogTheme.FluentLight => App.FluentLight, - CatalogTheme.FluentDark => App.FluentDark, - CatalogTheme.DefaultLight => App.DefaultLight, - CatalogTheme.DefaultDark => App.DefaultDark, - _ => Application.Current.Styles[0] - }; + Application.Current.Styles[0] = App.DefaultDark; + Application.Current.Styles[1] = App.DataGridDefault; + } } }; diff --git a/src/Avalonia.Themes.Fluent/FluentTheme.cs b/src/Avalonia.Themes.Fluent/FluentTheme.cs index 43b71567fa..53be41e4d1 100644 --- a/src/Avalonia.Themes.Fluent/FluentTheme.cs +++ b/src/Avalonia.Themes.Fluent/FluentTheme.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using Avalonia.Markup.Xaml.Styling; using Avalonia.Styling; #nullable enable @@ -17,11 +18,14 @@ namespace Avalonia.Themes.Fluent /// /// Includes the fluent theme in an application. /// - public class FluentTheme : IStyle, IResourceProvider + public class FluentTheme : AvaloniaObject, IStyle, IResourceProvider { private readonly Uri _baseUri; - private IStyle[]? _loaded; + private Styles _fluentDark = new(); + private Styles _fluentLight = new(); + private Styles _sharedStyles = new(); private bool _isLoading; + private IStyle? _loaded; /// /// Initializes a new instance of the class. @@ -30,6 +34,7 @@ namespace Avalonia.Themes.Fluent public FluentTheme(Uri baseUri) { _baseUri = baseUri; + InitStyles(baseUri); } /// @@ -39,12 +44,37 @@ namespace Avalonia.Themes.Fluent public FluentTheme(IServiceProvider serviceProvider) { _baseUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext))).BaseUri; + InitStyles(_baseUri); } + + public static readonly StyledProperty ModeProperty = + AvaloniaProperty.Register(nameof(Mode)); /// /// Gets or sets the mode of the fluent theme (light, dark). /// - public FluentThemeMode Mode { get; set; } + public FluentThemeMode Mode + { + get => GetValue(ModeProperty); + set => SetValue(ModeProperty, value); + } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property == ModeProperty) + { + if (Mode == FluentThemeMode.Dark) + { + (Loaded as Styles)![1] = _fluentDark[0]; + (Loaded as Styles)![2] = _fluentDark[1]; + } + else + { + (Loaded as Styles)![1] = _fluentLight[0]; + (Loaded as Styles)![2] = _fluentLight[1]; + } + } + } public IResourceHost? Owner => (Loaded as IResourceProvider)?.Owner; @@ -58,18 +88,25 @@ namespace Avalonia.Themes.Fluent if (_loaded == null) { _isLoading = true; - var loaded = (IStyle)AvaloniaXamlLoader.Load(GetUri(), _baseUri); - _loaded = new[] { loaded }; + + if (Mode == FluentThemeMode.Light) + { + _loaded = new Styles() { _sharedStyles , _fluentLight[0], _fluentLight[1] }; + } + else if (Mode == FluentThemeMode.Dark) + { + _loaded = new Styles() { _sharedStyles, _fluentDark[0], _fluentDark[1] }; + } _isLoading = false; } - return _loaded?[0]!; + return _loaded!; } } bool IResourceNode.HasResources => (Loaded as IResourceProvider)?.HasResources ?? false; - IReadOnlyList IStyle.Children => _loaded ?? Array.Empty(); + IReadOnlyList IStyle.Children => _loaded?.Children ?? Array.Empty(); public event EventHandler OwnerChanged { @@ -105,10 +142,47 @@ namespace Avalonia.Themes.Fluent void IResourceProvider.AddOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.AddOwner(owner); void IResourceProvider.RemoveOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.RemoveOwner(owner); - private Uri GetUri() => Mode switch + private void InitStyles(Uri baseUri) { - FluentThemeMode.Dark => new Uri("avares://Avalonia.Themes.Fluent/FluentDark.xaml", UriKind.Absolute), - _ => new Uri("avares://Avalonia.Themes.Fluent/FluentLight.xaml", UriKind.Absolute), - }; + _sharedStyles = new Styles + { + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/AccentColors.xaml") + }, + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml") + }, + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Controls/FluentControls.xaml") + } + }; + + _fluentLight = new Styles + { + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml") + }, + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml") + } + }; + + _fluentDark = new Styles + { + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml") + }, + new StyleInclude(baseUri) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml") + } + }; + } } }