From c1f950343bcd9698c982c8bcc8133e137659cd7d Mon Sep 17 00:00:00 2001 From: hmishra Date: Mon, 22 Jul 2024 21:36:32 +0530 Subject: [PATCH 1/2] Sync window theme mode with resource dictionary updates --- .../System/Windows/ThemeManager3.cs | 9 ++++- .../System/Windows/TreeWalkHelper.cs | 37 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) 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..d55571f4ac6 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager3.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager3.cs @@ -231,7 +231,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)) @@ -365,7 +365,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; @@ -376,6 +376,11 @@ private static void AddOrUpdateThemeResources(ResourceDictionary rd, Uri diction if (index >= 0) { + if(isWindowUpdate && rd.MergedDictionaries[index].Source.ToString().Equals(dictionaryUri.ToString(), StringComparison.OrdinalIgnoreCase)) + { + return; + } + rd.MergedDictionaries[index] = newDictionary; } else 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..6e443070f12 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs @@ -14,6 +14,7 @@ using System; using System.Diagnostics; using System.Security; +using System.Collections.ObjectModel; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Documents; @@ -680,6 +681,42 @@ private static void InvalidateResourceReferences( { Debug.Assert(d != null, "Must have non-null current node"); + Window currentWindow = d as Window; + + if(currentWindow != null) + { + Collection windowResources = currentWindow.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")) + { + currentWindow.ThemeMode = ThemeMode.Light; + } + else if(windowResources[i].Source.ToString().Contains("Dark")) + { + currentWindow.ThemeMode = ThemeMode.Dark; + } + else + { + currentWindow.ThemeMode = ThemeMode.System; + } + + break; + } + } + + if(!containsFluentResource) + { + currentWindow.ThemeMode = ThemeMode.None; + } + } + // Find properties that have resource reference value LocalValueEnumerator localValues = d.GetLocalValueEnumerator(); int localValuesCount = localValues.Count; From 5a7241a5b7606c395e488ee4db3a1ba0cbd0e850 Mon Sep 17 00:00:00 2001 From: hmishra Date: Mon, 22 Jul 2024 23:46:43 +0530 Subject: [PATCH 2/2] Fix resync bug causing window ThemeMode to not hold ThemeMode.System --- .../System/Windows/ThemeManager3.cs | 41 +++++++++++++++++++ .../System/Windows/TreeWalkHelper.cs | 34 +-------------- 2 files changed, 43 insertions(+), 32 deletions(-) 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 d55571f4ac6..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; @@ -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(); @@ -374,6 +411,8 @@ 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)) @@ -387,6 +426,8 @@ private static void AddOrUpdateThemeResources(ResourceDictionary rd, Uri diction { 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 6e443070f12..4f5eef3bc09 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TreeWalkHelper.cs @@ -14,7 +14,6 @@ using System; using System.Diagnostics; using System.Security; -using System.Collections.ObjectModel; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Documents; @@ -683,38 +682,9 @@ private static void InvalidateResourceReferences( Window currentWindow = d as Window; - if(currentWindow != null) + if(currentWindow != null && !ThemeManager3.IgnoreWindowResourcesChange) { - Collection windowResources = currentWindow.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")) - { - currentWindow.ThemeMode = ThemeMode.Light; - } - else if(windowResources[i].Source.ToString().Contains("Dark")) - { - currentWindow.ThemeMode = ThemeMode.Dark; - } - else - { - currentWindow.ThemeMode = ThemeMode.System; - } - - break; - } - } - - if(!containsFluentResource) - { - currentWindow.ThemeMode = ThemeMode.None; - } + ThemeManager3.SyncWindowThemeModeAndResources(currentWindow); } // Find properties that have resource reference value