diff --git a/src/Avalonia.Visuals/AvaloniaPropertyExtensions.cs b/src/Avalonia.Visuals/AvaloniaPropertyExtensions.cs
new file mode 100644
index 0000000000..6aaa224b00
--- /dev/null
+++ b/src/Avalonia.Visuals/AvaloniaPropertyExtensions.cs
@@ -0,0 +1,27 @@
+using Avalonia.Media;
+
+#nullable enable
+
+namespace Avalonia
+{
+ ///
+ /// Extensions for .
+ ///
+ public static class AvaloniaPropertyExtensions
+ {
+ ///
+ /// Checks if values of given property can affect rendering (via ).
+ ///
+ /// Property to check.
+ public static bool CanValueAffectRender(this AvaloniaProperty property)
+ {
+ var propertyType = property.PropertyType;
+
+ // Only case that we are sure that property value CAN'T affect render are sealed types that don't implement
+ // the interface.
+ var cannotAffectRender = propertyType.IsSealed && !typeof(IAffectsRender).IsAssignableFrom(propertyType);
+
+ return !cannotAffectRender;
+ }
+ }
+}
diff --git a/src/Avalonia.Visuals/Media/Brush.cs b/src/Avalonia.Visuals/Media/Brush.cs
index f36cd88537..0d08f92685 100644
--- a/src/Avalonia.Visuals/Media/Brush.cs
+++ b/src/Avalonia.Visuals/Media/Brush.cs
@@ -69,14 +69,14 @@ namespace Avalonia.Media
protected static void AffectsRender(params AvaloniaProperty[] properties)
where T : Brush
{
- void Invalidate(AvaloniaPropertyChangedEventArgs e)
+ static void Invalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as T)?.RaiseInvalidated(EventArgs.Empty);
}
foreach (var property in properties)
{
- property.Changed.Subscribe(Invalidate);
+ property.Changed.Subscribe(e => Invalidate(e));
}
}
diff --git a/src/Avalonia.Visuals/Media/Pen.cs b/src/Avalonia.Visuals/Media/Pen.cs
index b88fae28ff..8ab2b11331 100644
--- a/src/Avalonia.Visuals/Media/Pen.cs
+++ b/src/Avalonia.Visuals/Media/Pen.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
-using System.Collections.Generic;
using Avalonia.Media.Immutable;
using Avalonia.Utilities;
@@ -197,7 +196,15 @@ namespace Avalonia.Media
protected static void AffectsRender(params AvaloniaProperty[] properties)
where T : Pen
{
- void Invalidate(AvaloniaPropertyChangedEventArgs e)
+ static void Invalidate(AvaloniaPropertyChangedEventArgs e)
+ {
+ if (e.Sender is T sender)
+ {
+ sender.RaiseInvalidated(EventArgs.Empty);
+ }
+ }
+
+ static void InvalidateAndSubscribe(AvaloniaPropertyChangedEventArgs e)
{
if (e.Sender is T sender)
{
@@ -223,7 +230,14 @@ namespace Avalonia.Media
foreach (var property in properties)
{
- property.Changed.Subscribe(Invalidate);
+ if (property.CanValueAffectRender())
+ {
+ property.Changed.Subscribe(e => InvalidateAndSubscribe(e));
+ }
+ else
+ {
+ property.Changed.Subscribe(e => Invalidate(e));
+ }
}
}
diff --git a/src/Avalonia.Visuals/Visual.cs b/src/Avalonia.Visuals/Visual.cs
index bd2ab6e614..d9032cfa3e 100644
--- a/src/Avalonia.Visuals/Visual.cs
+++ b/src/Avalonia.Visuals/Visual.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Specialized;
-using System.Linq;
using Avalonia.Collections;
using Avalonia.Data;
using Avalonia.Logging;
@@ -336,7 +335,15 @@ namespace Avalonia
protected static void AffectsRender(params AvaloniaProperty[] properties)
where T : Visual
{
- void Invalidate(AvaloniaPropertyChangedEventArgs e)
+ static void Invalidate(AvaloniaPropertyChangedEventArgs e)
+ {
+ if (e.Sender is T sender)
+ {
+ sender.InvalidateVisual();
+ }
+ }
+
+ static void InvalidateAndSubscribe(AvaloniaPropertyChangedEventArgs e)
{
if (e.Sender is T sender)
{
@@ -347,7 +354,7 @@ namespace Avalonia
if (e.NewValue is IAffectsRender newValue)
{
- WeakEventHandlerManager.Subscribe(newValue, nameof(newValue.Invalidated), sender.AffectsRenderInvalidated);
+ WeakEventHandlerManager.Subscribe(newValue, nameof(newValue.Invalidated), sender.AffectsRenderInvalidated);
}
sender.InvalidateVisual();
@@ -356,7 +363,14 @@ namespace Avalonia
foreach (var property in properties)
{
- property.Changed.Subscribe(Invalidate);
+ if (property.CanValueAffectRender())
+ {
+ property.Changed.Subscribe(e => InvalidateAndSubscribe(e));
+ }
+ else
+ {
+ property.Changed.Subscribe(e => Invalidate(e));
+ }
}
}