diff --git a/src/Avalonia.Controls/Border.cs b/src/Avalonia.Controls/Border.cs index 5f84421c64..c4bc121a27 100644 --- a/src/Avalonia.Controls/Border.cs +++ b/src/Avalonia.Controls/Border.cs @@ -43,8 +43,9 @@ namespace Avalonia.Controls /// static Border() { - AffectsRender(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty); + AffectsRender(BorderThicknessProperty, CornerRadiusProperty); AffectsMeasure(BorderThicknessProperty); + BrushAffectsRender(BackgroundProperty, BorderBrushProperty); } /// diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs index c0d211effb..9b768749df 100644 --- a/src/Avalonia.Controls/Panel.cs +++ b/src/Avalonia.Controls/Panel.cs @@ -30,6 +30,7 @@ namespace Avalonia.Controls /// static Panel() { + BrushAffectsRender(BackgroundProperty); ClipToBoundsProperty.OverrideDefaultValue(true); } diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs index 6badf91367..6c1d6e2cc1 100644 --- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs @@ -90,8 +90,9 @@ namespace Avalonia.Controls.Presenters /// static ContentPresenter() { - AffectsRender(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty); + AffectsRender(BorderThicknessProperty, CornerRadiusProperty); AffectsMeasure(BorderThicknessProperty, PaddingProperty); + BrushAffectsRender(BackgroundProperty, BorderBrushProperty); ContentProperty.Changed.AddClassHandler(x => x.ContentChanged); ContentTemplateProperty.Changed.AddClassHandler(x => x.ContentChanged); TemplatedParentProperty.Changed.AddClassHandler(x => x.TemplatedParentChanged); diff --git a/src/Avalonia.Controls/Shapes/Shape.cs b/src/Avalonia.Controls/Shapes/Shape.cs index 604051ef28..d2a4a37531 100644 --- a/src/Avalonia.Controls/Shapes/Shape.cs +++ b/src/Avalonia.Controls/Shapes/Shape.cs @@ -30,11 +30,11 @@ namespace Avalonia.Controls.Shapes private Geometry _renderedGeometry; bool _calculateTransformOnArrange = false; - static Shape() { AffectsMeasure(StretchProperty, StrokeThicknessProperty); - AffectsRender(FillProperty, StrokeProperty, StrokeDashArrayProperty); + AffectsRender(StrokeDashArrayProperty); + BrushAffectsRender(FillProperty, StrokeProperty); } public Geometry DefiningGeometry diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index e91d2e8fa7..8689d11e13 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -99,10 +99,10 @@ namespace Avalonia.Controls static TextBlock() { ClipToBoundsProperty.OverrideDefaultValue(true); - AffectsRender(ForegroundProperty); AffectsRender(FontWeightProperty); AffectsRender(FontSizeProperty); AffectsRender(FontStyleProperty); + BrushAffectsRender(BackgroundProperty, ForegroundProperty); } /// diff --git a/src/Avalonia.Visuals/Visual.cs b/src/Avalonia.Visuals/Visual.cs index 81e1a93a6f..8631d2001d 100644 --- a/src/Avalonia.Visuals/Visual.cs +++ b/src/Avalonia.Visuals/Visual.cs @@ -328,6 +328,44 @@ namespace Avalonia } } + /// + /// Indicates that a brush property change should cause to be + /// called. + /// + /// The properties. + /// + /// This method should be called in a control's static constructor with each property + /// on the control which when changed should cause a redraw. It not only triggers an + /// invalidation when the property itself changes, but also when the brush raises + /// the event. + /// + protected static void BrushAffectsRender(params AvaloniaProperty[] properties) + where T : Visual + { + void Invalidate(AvaloniaPropertyChangedEventArgs e) + { + if (e.Sender is T sender) + { + if (e.OldValue is IMutableBrush oldValue) + { + oldValue.Changed -= sender.BrushChanged; + } + + if (e.NewValue is IMutableBrush newValue) + { + newValue.Changed += sender.BrushChanged; + } + + sender.InvalidateVisual(); + } + } + + foreach (var property in properties) + { + property.Changed.Subscribe(Invalidate); + } + } + /// /// Calls the method /// for this control and all of its visual descendants. @@ -530,6 +568,8 @@ namespace Avalonia OnVisualParentChanged(old, value); } + private void BrushChanged(object sender, EventArgs e) => InvalidateVisual(); + /// /// Called when the collection changes. ///