diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs index d28872bdda3..189e0b08732 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs @@ -936,8 +936,8 @@ public ResourceDictionary Resources { if(value != null) { - var uri = ThemeManager.GetThemeResource(ThemeMode); - value.MergedDictionaries.Insert(0, new ResourceDictionary() { Source = uri }); + ResourceDictionary rd = ThemeManager.GetFluentThemeDictionary(ThemeMode); + value.MergedDictionaries.Insert(0, rd); } ThemeManager.DeferredAppThemeLoading = false; } @@ -993,6 +993,7 @@ public ThemeMode ThemeMode // If the resources are not initializd, // fluent dictionary included will be reset. // Hence, deferring the step. + ThemeManager.OnApplicationThemeChanged(oldValue, value); ThemeManager.DeferredAppThemeLoading = true; return; } @@ -1741,8 +1742,7 @@ internal void InvalidateResourceReferences(ResourcesChangeInfo info) // i.e. SkipAppThemeModeSyncing is set to true // - if application's ThemeMode and Resources sync is enabled. // i.e. IsAppThemeModeSyncEnabled is set to true - if (!ThemeManager.SkipAppThemeModeSyncing - && ThemeManager.IsAppThemeModeSyncEnabled) + if (!ThemeManager.SkipAppThemeModeSyncing) { ThemeManager.SyncThemeMode(); } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager.cs index d60eb222068..0e365c8ae4a 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager.cs @@ -24,8 +24,6 @@ internal static void OnSystemThemeChanged() { bool useLightColors = GetUseLightColors(Application.Current.ThemeMode); - var fluentThemeResourceUri = GetFluentThemeResourceUri(useLightColors); - FluentThemeState newFluentThemeState = new FluentThemeState(Application.Current.ThemeMode.Value, useLightColors); if (s_currentFluentThemeState == newFluentThemeState) @@ -33,7 +31,8 @@ internal static void OnSystemThemeChanged() return; } - AddOrUpdateThemeResources(Application.Current.Resources, fluentThemeResourceUri); + ResourceDictionary rd = GetFluentThemeDictionary(Application.Current.ThemeMode); + AddOrUpdateThemeResources(Application.Current.Resources, rd); foreach (Window window in Application.Current.Windows) { @@ -91,8 +90,8 @@ internal static void OnApplicationThemeChanged(ThemeMode oldThemeMode, ThemeMode } bool useLightColors = GetUseLightColors(newThemeMode); - var fluentThemeResourceUri = GetFluentThemeResourceUri(useLightColors); - AddOrUpdateThemeResources(Application.Current.Resources, fluentThemeResourceUri); + ResourceDictionary rd = GetFluentThemeDictionary(newThemeMode); + AddOrUpdateThemeResources(Application.Current.Resources, rd); foreach (Window window in Application.Current.Windows) { @@ -129,7 +128,7 @@ internal static bool SyncThemeMode() { ThemeMode themeMode = GetThemeModeFromResourceDictionary(Application.Current.Resources); - if (Application.Current.ThemeMode != themeMode) + if (Application.Current.ThemeMode != themeMode || themeMode == ThemeMode.System) { Application.Current.ThemeMode = themeMode; return themeMode == ThemeMode.None ? false : true; @@ -137,46 +136,6 @@ internal static bool SyncThemeMode() return false; } - internal static void SyncThemeModeAndResources() - { - // Since, this is called from window there is a possiblity that the application - // instance is null. Hence, we need to check for null. - if(Application.Current == null) - return; - - ThemeMode themeMode = Application.Current.ThemeMode; - var rd = Application.Current.Resources; - - bool resyncThemeMode = false; - int index = LastIndexOfFluentThemeDictionary(rd); - - if (index == -1) - { - // This means that ThemeMode was set but Resources were not set during initialization. - // Hence we need to resync. - if (themeMode != ThemeMode.None) - { - resyncThemeMode = true; - } - } - else - { - // If index > 0, then Fluent theme dictionary was added manually. - // If ThemeMode is None, and yet there is a Fluent theme dictionary, hence that was manually set. - // Hence we need to resync. - if (index > 0 || themeMode == ThemeMode.None) - { - themeMode = GetThemeModeFromSourceUri(rd.MergedDictionaries[index].Source); - resyncThemeMode = true; - } - } - - if (resyncThemeMode) - { - Application.Current.ThemeMode = themeMode; - } - } - internal static void ApplyStyleOnWindow(Window window) { if (!IsFluentThemeEnabled && window.ThemeMode == ThemeMode.None) @@ -204,10 +163,36 @@ internal static bool IsValidThemeMode(ThemeMode themeMode) || themeMode == ThemeMode.System; } - internal static Uri GetThemeResource(ThemeMode themeMode) + internal static ResourceDictionary GetFluentThemeDictionary(ThemeMode themeMode) { + if (themeMode == ThemeMode.None) + { + return null; + } + + if ( SystemParameters.HighContrast) + { + return new ResourceDictionary() { Source = new Uri(FluentThemeResourceDictionaryUri + "Fluent.HC.xaml", UriKind.Absolute) }; + } + + ResourceDictionary rd = null; bool useLightColors = GetUseLightColors(themeMode); - return GetFluentThemeResourceUri(useLightColors); + + if (themeMode == ThemeMode.System) + { + rd = new ResourceDictionary() { Source = new Uri(FluentThemeResourceDictionaryUri + "Fluent.xaml", UriKind.Absolute) }; + + var colorFileName = useLightColors ? "Light.xaml" : "Dark.xaml"; + Uri dictionaryUri = new Uri(FluentColorDictionaryUri + colorFileName, UriKind.Absolute); + rd.MergedDictionaries.Insert(0, new ResourceDictionary() { Source = dictionaryUri }); + } + else + { + var themeFileName = useLightColors ? "Fluent.Light.xaml" : "Fluent.Dark.xaml"; + rd = new ResourceDictionary() { Source = new Uri(FluentThemeResourceDictionaryUri + themeFileName, UriKind.Absolute) }; + } + + return rd; } #endregion @@ -258,8 +243,8 @@ private static void ApplyFluentOnWindow(Window window) return; bool useLightColors = GetUseLightColors(window.ThemeMode); - var fluentThemeResourceUri = GetFluentThemeResourceUri(useLightColors); - AddOrUpdateThemeResources(window.Resources, fluentThemeResourceUri); + ResourceDictionary rd = GetFluentThemeDictionary(window.ThemeMode); + AddOrUpdateThemeResources(window.Resources, rd); ApplyStyleOnWindow(window, useLightColors); if (!FluentEnabledWindows.HasItem(window)) @@ -316,8 +301,6 @@ private static void ApplyStyleOnWindow(Window window, bool useLightColors) #region Internal Properties - internal static bool IsAppThemeModeSyncEnabled { get; set; } = false; - internal static bool IsFluentThemeEnabled { get @@ -390,30 +373,11 @@ private static ThemeMode GetThemeModeFromSourceUri(Uri source) } } - private static Uri GetFluentThemeResourceUri(bool useLightMode) + private static void AddOrUpdateThemeResources(ResourceDictionary rd, ResourceDictionary newDictionary) { - string themeFileName; - - if (SystemParameters.HighContrast) - { - themeFileName = "Fluent.HC.xaml"; - } - else - { - themeFileName = useLightMode ? FluentLightDictionary : FluentDarkDictionary; - } - - return new Uri(FluentThemeResourceDictionaryUri + themeFileName, UriKind.Absolute); - } - - private static void AddOrUpdateThemeResources(ResourceDictionary rd, Uri dictionaryUri) - { - if (rd == null) + if (rd == null || newDictionary == null) return; - ArgumentNullException.ThrowIfNull(dictionaryUri); - - var newDictionary = new ResourceDictionary() { Source = dictionaryUri }; int index = LastIndexOfFluentThemeDictionary(rd); if (index >= 0) @@ -485,6 +449,7 @@ private static bool IsSystemThemeLight() #region Private Fields + private const string FluentColorDictionaryUri = "pack://application:,,,/PresentationFramework.Fluent;component/Resources/Theme/"; private const string FluentThemeResourceDictionaryUri = "pack://application:,,,/PresentationFramework.Fluent;component/Themes/"; private const string RegPersonalizeKeyPath = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; private const string FluentLightDictionary = "Fluent.Light.xaml"; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs index 9f467d192d2..ded2795107a 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs @@ -2558,24 +2558,9 @@ internal void CreateSourceWindow(bool duringShow) if (Standard.Utility.IsOSWindows10OrNewer) { - if(!ThemeManager.IsAppThemeModeSyncEnabled) - { - ThemeManager.SyncThemeModeAndResources(); - ThemeManager.IsAppThemeModeSyncEnabled = true; - } - if(ThemeManager.IsFluentThemeEnabled) { - - if(ThemeManager.DeferredAppThemeLoading) - { - ThemeManager.OnApplicationThemeChanged(ThemeMode.None, Application.Current.ThemeMode); - ThemeManager.DeferredAppThemeLoading = false; - } - else - { - ThemeManager.ApplyStyleOnWindow(this); - } + ThemeManager.ApplyStyleOnWindow(this); } if(_deferThemeLoading)