diff --git a/src/Avalonia.Base/Data/BindingNotification.cs b/src/Avalonia.Base/Data/BindingNotification.cs
index d61e9ad3b2..c9e6e3b804 100644
--- a/src/Avalonia.Base/Data/BindingNotification.cs
+++ b/src/Avalonia.Base/Data/BindingNotification.cs
@@ -166,6 +166,21 @@ namespace Avalonia.Data
return !(a == b);
}
+ ///
+ /// Gets a value from an object that may be a .
+ ///
+ /// The object.
+ /// The value.
+ ///
+ /// If is a then returns the binding
+ /// notification's . If not, returns the object unchanged.
+ ///
+ public static object ExtractValue(object o)
+ {
+ var notification = o as BindingNotification;
+ return notification != null ? notification.Value : o;
+ }
+
///
/// Compares an object to an instance of for equality.
///
diff --git a/src/Avalonia.Base/Data/BindingOperations.cs b/src/Avalonia.Base/Data/BindingOperations.cs
index 9899eb633c..eb7c449bec 100644
--- a/src/Avalonia.Base/Data/BindingOperations.cs
+++ b/src/Avalonia.Base/Data/BindingOperations.cs
@@ -54,7 +54,10 @@ namespace Avalonia.Data
if (source != null)
{
- return source.Take(1).Subscribe(x => target.SetValue(property, x, binding.Priority));
+ return source
+ .Where(x => BindingNotification.ExtractValue(x) != AvaloniaProperty.UnsetValue)
+ .Take(1)
+ .Subscribe(x => target.SetValue(property, x, binding.Priority));
}
else
{
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
index 5c3459e3db..1757550d4a 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
@@ -54,6 +54,36 @@ namespace Avalonia.Base.UnitTests
Assert.False(target.IsSet(Class1.QuxProperty));
}
+ [Fact]
+ public void OneTime_Binding_Ignores_UnsetValue()
+ {
+ var target = new Class1();
+ var source = new Subject