diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager3.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager3.cs index 9ebc4a95389..56632918f0f 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager3.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager3.cs @@ -1,6 +1,7 @@ using Standard; using Microsoft.Win32; using System.Collections; +using System.Collections.ObjectModel; using System.Collections.Generic; using System.Windows.Interop; using System.Windows.Media; @@ -156,6 +157,40 @@ internal static void SyncDeferredThemeModeAndResources() } } + internal static void SyncWindowThemeModeAndResources(Window window) + { + Collection windowResources = window.Resources.MergedDictionaries; + bool containsFluentResource = false; + + for (int i = windowResources.Count - 1 ; i >= 0 ; i--) + { + if (windowResources[i].Source.ToString().Contains("Fluent")) + { + containsFluentResource = true; + + if(windowResources[i].Source.ToString().Contains("Light")) + { + window.ThemeMode = ThemeMode.Light; + } + else if(windowResources[i].Source.ToString().Contains("Dark")) + { + window.ThemeMode = ThemeMode.Dark; + } + else + { + window.ThemeMode = ThemeMode.System; + } + + break; + } + } + + if(!containsFluentResource) + { + window.ThemeMode = ThemeMode.None; + } + } + internal static void ApplyStyleOnWindow(Window window) { if(!IsFluentThemeEnabled && window.ThemeMode == ThemeMode.None) return; @@ -231,7 +266,7 @@ private static void ApplyFluentOnWindow(Window window) bool useLightColors = GetUseLightColors(window.ThemeMode); var fluentThemeResourceUri = GetFluentThemeResourceUri(useLightColors); - AddOrUpdateThemeResources(window.Resources, fluentThemeResourceUri); + AddOrUpdateThemeResources(window.Resources, fluentThemeResourceUri, true); ApplyStyleOnWindow(window, useLightColors); if(!FluentEnabledWindows.HasItem(window)) @@ -300,6 +335,8 @@ internal static bool IsFluentThemeEnabled internal static bool IgnoreAppResourcesChange { get; set; } = false; + internal static bool IgnoreWindowResourcesChange { get; set; } = false; + internal static double DefaultFluentThemeFontSize => 14; internal static WindowCollection FluentEnabledWindows { get; set; } = new WindowCollection(); @@ -365,7 +402,7 @@ private static Uri GetFluentThemeResourceUri(bool useLightMode) } - private static void AddOrUpdateThemeResources(ResourceDictionary rd, Uri dictionaryUri) + private static void AddOrUpdateThemeResources(ResourceDictionary rd, Uri dictionaryUri, bool isWindowUpdate = false) { if (rd == null) return; @@ -374,14 +411,23 @@ private static void AddOrUpdateThemeResources(ResourceDictionary rd, Uri diction var newDictionary = new ResourceDictionary() { Source = dictionaryUri }; int index = FindLastFluentThemeResourceDictionaryIndex(rd); + IgnoreWindowResourcesChange = true; + if (index >= 0) { + if(isWindowUpdate && rd.MergedDictionaries[index].Source.ToString().Equals(dictionaryUri.ToString(), StringComparison.OrdinalIgnoreCase)) + { + return; + } + rd.MergedDictionaries[index] = newDictionary; } else { rd.MergedDictionaries.Insert(0, newDictionary); } + + IgnoreWindowResourcesChange = false; } private static int FindLastFluentThemeResourceDictionaryIndex(ResourceDictionary rd) diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs index 1489ff80f3b..4f5eef3bc09 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs @@ -680,6 +680,13 @@ private static void InvalidateResourceReferences( { Debug.Assert(d != null, "Must have non-null current node"); + Window currentWindow = d as Window; + + if(currentWindow != null && !ThemeManager3.IgnoreWindowResourcesChange) + { + ThemeManager3.SyncWindowThemeModeAndResources(currentWindow); + } + // Find properties that have resource reference value LocalValueEnumerator localValues = d.GetLocalValueEnumerator(); int localValuesCount = localValues.Count;