diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs
index 7a0ae7d1d9..e54dc13a83 100644
--- a/src/Avalonia.Base/AvaloniaObject.cs
+++ b/src/Avalonia.Base/AvaloniaObject.cs
@@ -611,7 +611,7 @@ namespace Avalonia
internal IDisposable Bind(
AvaloniaProperty property,
- BindingExpression expression,
+ UntypedBindingExpressionBase expression,
BindingPriority priority)
{
return property.RouteBind(this, expression, priority);
diff --git a/src/Avalonia.Base/AvaloniaProperty.cs b/src/Avalonia.Base/AvaloniaProperty.cs
index 48993ee402..934bb29cde 100644
--- a/src/Avalonia.Base/AvaloniaProperty.cs
+++ b/src/Avalonia.Base/AvaloniaProperty.cs
@@ -569,7 +569,7 @@ namespace Avalonia
/// The priority.
internal abstract IDisposable RouteBind(
AvaloniaObject o,
- BindingExpression source,
+ UntypedBindingExpressionBase source,
BindingPriority priority);
///
diff --git a/src/Avalonia.Base/Data/BindingNotification.cs b/src/Avalonia.Base/Data/BindingNotification.cs
index a58059d891..ed017e29a1 100644
--- a/src/Avalonia.Base/Data/BindingNotification.cs
+++ b/src/Avalonia.Base/Data/BindingNotification.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
namespace Avalonia.Data
{
@@ -288,4 +289,17 @@ namespace Avalonia.Data
a?.Message == b?.Message;
}
}
+
+ internal static class BindingErrorTypeExtensions
+ {
+ public static BindingValueType ToBindingValueType(this BindingErrorType type)
+ {
+ return type switch
+ {
+ BindingErrorType.Error => BindingValueType.BindingError,
+ BindingErrorType.DataValidationError => BindingValueType.DataValidationError,
+ _ => BindingValueType.Value,
+ };
+ }
+ }
}
diff --git a/src/Avalonia.Base/Data/BindingOperations.cs b/src/Avalonia.Base/Data/BindingOperations.cs
index 1dd845cded..be7218950f 100644
--- a/src/Avalonia.Base/Data/BindingOperations.cs
+++ b/src/Avalonia.Base/Data/BindingOperations.cs
@@ -24,7 +24,7 @@ namespace Avalonia.Data
_ = property ?? throw new ArgumentNullException(nameof(property));
_ = binding ?? throw new ArgumentNullException(nameof(binding));
- if (binding.Source is BindingExpression expression)
+ if (binding.Expression is { } expression)
{
return target.Bind(property, expression, BindingPriority.LocalValue);
}
diff --git a/src/Avalonia.Base/Data/Core/BindingError.cs b/src/Avalonia.Base/Data/Core/BindingError.cs
new file mode 100644
index 0000000000..b1cc9b9caf
--- /dev/null
+++ b/src/Avalonia.Base/Data/Core/BindingError.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Diagnostics;
+
+namespace Avalonia.Data.Core;
+
+internal class BindingError
+{
+ public BindingError(Exception exception, BindingErrorType errorType)
+ {
+ Debug.Assert(errorType != BindingErrorType.None);
+
+ Exception = exception;
+ ErrorType = errorType;
+ }
+
+ public Exception Exception { get; }
+ public BindingErrorType ErrorType { get; }
+}
diff --git a/src/Avalonia.Base/Data/Core/BindingExpression.Observable.cs b/src/Avalonia.Base/Data/Core/BindingExpression.Observable.cs
deleted file mode 100644
index 121e455fb8..0000000000
--- a/src/Avalonia.Base/Data/Core/BindingExpression.Observable.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using System;
-
-namespace Avalonia.Data.Core;
-
-// Mostly for unit tests, BindingExpression implements IObservable