diff --git a/src/Avalonia.Base/AvaloniaProperty.cs b/src/Avalonia.Base/AvaloniaProperty.cs
index 62ca971412..fd43ced196 100644
--- a/src/Avalonia.Base/AvaloniaProperty.cs
+++ b/src/Avalonia.Base/AvaloniaProperty.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Avalonia.Data;
using Avalonia.Data.Core;
+using Avalonia.Styling;
using Avalonia.Utilities;
namespace Avalonia
@@ -454,15 +455,6 @@ namespace Avalonia
return Name;
}
- ///
- /// Uses the visitor pattern to resolve an untyped property to a typed property.
- ///
- /// The type of user data passed.
- /// The visitor which will accept the typed property.
- /// The user data to pass.
- public abstract void Accept(IAvaloniaPropertyVisitor visitor, ref TData data)
- where TData : struct;
-
///
/// Routes an untyped ClearValue call to a typed call.
///
@@ -508,6 +500,7 @@ namespace Avalonia
BindingPriority priority);
internal abstract void RouteInheritanceParentChanged(AvaloniaObject o, AvaloniaObject? oldParent);
+ internal abstract ISetterInstance CreateSetterInstance(IStyleable target, object? value);
///
/// Overrides the metadata for the property on the specified type.
diff --git a/src/Avalonia.Base/DirectPropertyBase.cs b/src/Avalonia.Base/DirectPropertyBase.cs
index 6e3baea99b..9c1ffce24c 100644
--- a/src/Avalonia.Base/DirectPropertyBase.cs
+++ b/src/Avalonia.Base/DirectPropertyBase.cs
@@ -1,6 +1,7 @@
using System;
using Avalonia.Data;
using Avalonia.Reactive;
+using Avalonia.Styling;
using Avalonia.Utilities;
namespace Avalonia
@@ -120,12 +121,6 @@ namespace Avalonia
base.OverrideMetadata(type, metadata);
}
- ///
- public override void Accept(IAvaloniaPropertyVisitor visitor, ref TData data)
- {
- visitor.Visit(this, ref data);
- }
-
///
internal override void RouteClearValue(AvaloniaObject o)
{
@@ -181,5 +176,30 @@ namespace Avalonia
{
throw new NotSupportedException("Direct properties do not support inheritance.");
}
+
+ internal override ISetterInstance CreateSetterInstance(IStyleable target, object? value)
+ {
+ if (value is IBinding binding)
+ {
+ return new PropertySetterBindingInstance(
+ target,
+ this,
+ binding);
+ }
+ else if (value is ITemplate template && !typeof(ITemplate).IsAssignableFrom(PropertyType))
+ {
+ return new PropertySetterLazyInstance(
+ target,
+ this,
+ () => (TValue)template.Build());
+ }
+ else
+ {
+ return new PropertySetterInstance(
+ target,
+ this,
+ (TValue)value!);
+ }
+ }
}
}
diff --git a/src/Avalonia.Base/StyledPropertyBase.cs b/src/Avalonia.Base/StyledPropertyBase.cs
index f94723866a..dd5eb703ea 100644
--- a/src/Avalonia.Base/StyledPropertyBase.cs
+++ b/src/Avalonia.Base/StyledPropertyBase.cs
@@ -2,6 +2,7 @@ using System;
using System.Diagnostics;
using Avalonia.Data;
using Avalonia.Reactive;
+using Avalonia.Styling;
using Avalonia.Utilities;
namespace Avalonia
@@ -158,12 +159,6 @@ namespace Avalonia
base.OverrideMetadata(type, metadata);
}
- ///
- public override void Accept(IAvaloniaPropertyVisitor visitor, ref TData data)
- {
- visitor.Visit(this, ref data);
- }
-
///
/// Gets the string representation of the property.
///
@@ -237,6 +232,31 @@ namespace Avalonia
o.InheritanceParentChanged(this, oldParent);
}
+ internal override ISetterInstance CreateSetterInstance(IStyleable target, object? value)
+ {
+ if (value is IBinding binding)
+ {
+ return new PropertySetterBindingInstance(
+ target,
+ this,
+ binding);
+ }
+ else if (value is ITemplate template && !typeof(ITemplate).IsAssignableFrom(PropertyType))
+ {
+ return new PropertySetterLazyInstance(
+ target,
+ this,
+ () => (TValue)template.Build());
+ }
+ else
+ {
+ return new PropertySetterInstance(
+ target,
+ this,
+ (TValue)value!);
+ }
+ }
+
private object? GetDefaultBoxedValue(Type type)
{
_ = type ?? throw new ArgumentNullException(nameof(type));
diff --git a/src/Avalonia.Base/Styling/Setter.cs b/src/Avalonia.Base/Styling/Setter.cs
index 168a882499..b4b3399022 100644
--- a/src/Avalonia.Base/Styling/Setter.cs
+++ b/src/Avalonia.Base/Styling/Setter.cs
@@ -16,7 +16,7 @@ namespace Avalonia.Styling
/// A is used to set a value on a
/// depending on a condition.
///
- public class Setter : ISetter, IAnimationSetter, IAvaloniaPropertyVisitor
+ public class Setter : ISetter, IAnimationSetter
{
private object? _value;
@@ -68,68 +68,7 @@ namespace Avalonia.Styling
throw new InvalidOperationException("Setter.Property must be set.");
}
- var data = new SetterVisitorData
- {
- target = target,
- value = Value,
- };
-
- Property.Accept(this, ref data);
- return data.result!;
- }
-
- void IAvaloniaPropertyVisitor.Visit(
- StyledPropertyBase property,
- ref SetterVisitorData data)
- {
- if (data.value is IBinding binding)
- {
- data.result = new PropertySetterBindingInstance(
- data.target,
- property,
- binding);
- }
- else if (data.value is ITemplate template && !typeof(ITemplate).IsAssignableFrom(property.PropertyType))
- {
- data.result = new PropertySetterLazyInstance(
- data.target,
- property,
- () => (T)template.Build());
- }
- else
- {
- data.result = new PropertySetterInstance(
- data.target,
- property,
- (T)data.value!);
- }
- }
-
- void IAvaloniaPropertyVisitor.Visit(
- DirectPropertyBase property,
- ref SetterVisitorData data)
- {
- if (data.value is IBinding binding)
- {
- data.result = new PropertySetterBindingInstance(
- data.target,
- property,
- binding);
- }
- else if (data.value is ITemplate template && !typeof(ITemplate).IsAssignableFrom(property.PropertyType))
- {
- data.result = new PropertySetterLazyInstance(
- data.target,
- property,
- () => (T)template.Build());
- }
- else
- {
- data.result = new PropertySetterInstance(
- data.target,
- property,
- (T)data.value!);
- }
+ return Property.CreateSetterInstance(target, Value);
}
private struct SetterVisitorData
diff --git a/src/Avalonia.Base/Utilities/IAvaloniaPropertyVisitor.cs b/src/Avalonia.Base/Utilities/IAvaloniaPropertyVisitor.cs
deleted file mode 100644
index 6a8df91b81..0000000000
--- a/src/Avalonia.Base/Utilities/IAvaloniaPropertyVisitor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace Avalonia.Utilities
-{
- ///
- /// A visitor to resolve an untyped to a typed property.
- ///
- /// The type of user data passed.
- ///
- /// Pass an instance that implements this interface to
- ///
- /// in order to resolve un untyped to a typed
- /// or .
- ///
- public interface IAvaloniaPropertyVisitor
- where TData : struct
- {
- ///
- /// Called when the property is a styled property.
- ///
- /// The property value type.
- /// The property.
- /// The user data.
- void Visit(StyledPropertyBase property, ref TData data);
-
- ///
- /// Called when the property is a direct property.
- ///
- /// The property value type.
- /// The property.
- /// The user data.
- void Visit(DirectPropertyBase property, ref TData data);
- }
-}
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs
index ee29c82345..f3f39b465b 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Avalonia.Data;
+using Avalonia.Styling;
using Avalonia.Utilities;
using Xunit;
@@ -146,11 +147,6 @@ namespace Avalonia.Base.UnitTests
OverrideMetadata(typeof(T), metadata);
}
- public override void Accept(IAvaloniaPropertyVisitor vistor, ref TData data)
- {
- throw new NotImplementedException();
- }
-
internal override IDisposable RouteBind(
AvaloniaObject o,
IObservable> source,
@@ -186,6 +182,11 @@ namespace Avalonia.Base.UnitTests
{
throw new NotImplementedException();
}
+
+ internal override ISetterInstance CreateSetterInstance(IStyleable target, object value)
+ {
+ throw new NotImplementedException();
+ }
}
private class Class1 : AvaloniaObject