From df4408d8c34daf9c49587e912e6d31d4e7c71060 Mon Sep 17 00:00:00 2001 From: GID Date: Tue, 16 Sep 2025 17:29:32 +0700 Subject: [PATCH 1/2] Simplify foreground inheritance checks Refactor foreground inheritance logic in IconElement. --- .../Controls/IconElement.cs | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/source/iNKORE.UI.WPF.Modern/Controls/IconElement.cs b/source/iNKORE.UI.WPF.Modern/Controls/IconElement.cs index 7d373cc7..fa8b6cc4 100644 --- a/source/iNKORE.UI.WPF.Modern/Controls/IconElement.cs +++ b/source/iNKORE.UI.WPF.Modern/Controls/IconElement.cs @@ -1,4 +1,4 @@ -using iNKORE.UI.WPF.Modern.Common; +using iNKORE.UI.WPF.Modern.Common; using System; using System.ComponentModel; using System.Windows; @@ -41,6 +41,8 @@ private void OnForegroundPropertyChanged(DependencyPropertyChangedEventArgs args var baseValueSource = DependencyPropertyHelper.GetValueSource(this, args.Property).BaseValueSource; _isForegroundDefaultOrInherited = baseValueSource <= BaseValueSource.Inherited; UpdateShouldInheritForegroundFromVisualParent(); + // Notify derived classes so they can push Foreground to internal visuals when not inheriting. + OnOwnForegroundPropertyChanged(args); } /// @@ -116,11 +118,30 @@ private protected virtual void OnShouldInheritForegroundFromVisualParentChanged( private void UpdateShouldInheritForegroundFromVisualParent() { + // Legacy logic (before simplification) kept for reference: + // We originally required that the element had both a logical Parent and a VisualParent and that they differed. + // This proved too restrictive in scenarios where the logical and visual tree relationships caused FontIcon + // to miss theme brush updates (e.g., in the iconography gallery) leaving glyphs with a stale/dark brush. + // + // ShouldInheritForegroundFromVisualParent = + // _isForegroundDefaultOrInherited && + // Parent != null && + // VisualParent != null && + // Parent != VisualParent; + + // if our Foreground is default/inherited and we have a visual parent, bind to it. ShouldInheritForegroundFromVisualParent = _isForegroundDefaultOrInherited && - Parent != null && - VisualParent != null && - Parent != VisualParent; + VisualParent != null; // Always inherit from visual parent when our Foreground is default/inherited. + } + + /// + /// Called whenever this element's own Foreground property changes (after inheritance logic updated). + /// Allows derived classes to propagate the Foreground to visual children when not inheriting directly from visual parent. + /// + /// Change args. + private protected virtual void OnOwnForegroundPropertyChanged(DependencyPropertyChangedEventArgs args) + { } private protected UIElementCollection Children From 842f5d1a545e049367a375d227a27035e558002a Mon Sep 17 00:00:00 2001 From: GID Date: Tue, 16 Sep 2025 17:30:28 +0700 Subject: [PATCH 2/2] Refactor FontIcon foreground handling with data binding Updated foreground handling in FontIcon to use data binding instead of manual property assignments. Removed legacy foreground inheritance logic. --- .../iNKORE.UI.WPF.Modern/Controls/FontIcon.cs | 74 ++++++++++++------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/source/iNKORE.UI.WPF.Modern/Controls/FontIcon.cs b/source/iNKORE.UI.WPF.Modern/Controls/FontIcon.cs index a8a30e9c..64e68452 100644 --- a/source/iNKORE.UI.WPF.Modern/Controls/FontIcon.cs +++ b/source/iNKORE.UI.WPF.Modern/Controls/FontIcon.cs @@ -1,4 +1,4 @@ -using iNKORE.UI.WPF.Modern.Common; +using iNKORE.UI.WPF.Modern.Common; using iNKORE.UI.WPF.Modern.Common.IconKeys; using System.ComponentModel; using System.Windows; @@ -235,37 +235,57 @@ private protected override void InitializeChildren() FontWeight = FontWeight, Text = Glyph }; - - if (ShouldInheritForegroundFromVisualParent) + // Instead of manually copying brushes, just bind. WPF inheritance will supply parent Foreground + // when our own Foreground is default; explicit user-set Foreground flows through. + _textBlock.SetBinding(TextBlock.ForegroundProperty, new System.Windows.Data.Binding { - _textBlock.Foreground = VisualParentForeground; - } + Path = new PropertyPath(nameof(Foreground)), + Source = this + }); Children.Add(_textBlock); } - private protected override void OnShouldInheritForegroundFromVisualParentChanged() - { - if (_textBlock != null) - { - if (ShouldInheritForegroundFromVisualParent) - { - _textBlock.Foreground = VisualParentForeground; - } - else - { - _textBlock.ClearValue(TextBlock.ForegroundProperty); - } - } - } - - private protected override void OnVisualParentForegroundPropertyChanged(DependencyPropertyChangedEventArgs args) - { - if (ShouldInheritForegroundFromVisualParent && _textBlock != null) - { - _textBlock.Foreground = (Brush)args.NewValue; - } - } + // Foreground propagation now handled purely via binding; overrides no longer necessary. + // Legacy foreground inheritance logic (kept for reference only): + // + // private protected override void OnShouldInheritForegroundFromVisualParentChanged() + // { + // if (_textBlock != null) + // { + // if (ShouldInheritForegroundFromVisualParent) + // { + // _textBlock.Foreground = VisualParentForeground; + // } + // else + // { + // _textBlock.ClearValue(TextBlock.ForegroundProperty); + // // Apply our own Foreground if explicitly set. + // if (Foreground != null) + // { + // _textBlock.Foreground = Foreground; + // } + // } + // } + // } + // + // private protected override void OnVisualParentForegroundPropertyChanged(DependencyPropertyChangedEventArgs args) + // { + // if (ShouldInheritForegroundFromVisualParent && _textBlock != null) + // { + // _textBlock.Foreground = (Brush)args.NewValue; + // } + // } + // + // private protected override void OnOwnForegroundPropertyChanged(DependencyPropertyChangedEventArgs args) + // { + // if (!ShouldInheritForegroundFromVisualParent && _textBlock != null) + // { + // // When we're not inheriting from visual parent, push our Foreground to the text block. + // _textBlock.Foreground = (Brush)args.NewValue; + // } + // } + // private TextBlock _textBlock;