Clear data validation when binding completes.
This commit is contained in:
@@ -9,11 +9,13 @@ namespace Avalonia.PropertyStore
|
||||
IDisposable
|
||||
{
|
||||
private readonly ValueStore _owner;
|
||||
private readonly bool _hasDataValidation;
|
||||
private IDisposable? _subscription;
|
||||
|
||||
public DirectBindingObserver(ValueStore owner, DirectPropertyBase<T> property)
|
||||
{
|
||||
_owner = owner;
|
||||
_hasDataValidation = property.GetMetadata(owner.Owner.GetType())?.EnableDataValidation ?? false;
|
||||
Property = property;
|
||||
}
|
||||
|
||||
@@ -33,10 +35,17 @@ namespace Avalonia.PropertyStore
|
||||
{
|
||||
_subscription?.Dispose();
|
||||
_subscription = null;
|
||||
_owner.OnLocalValueBindingCompleted(Property, this);
|
||||
OnCompleted();
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
_owner.OnLocalValueBindingCompleted(Property, this);
|
||||
|
||||
if (_hasDataValidation)
|
||||
_owner.Owner.OnUpdateDataValidation(Property, BindingValueType.UnsetValue, null);
|
||||
}
|
||||
|
||||
public void OnCompleted() => _owner.OnLocalValueBindingCompleted(Property, this);
|
||||
public void OnError(Exception error) => OnCompleted();
|
||||
|
||||
public void OnNext(T value)
|
||||
|
||||
@@ -10,11 +10,13 @@ namespace Avalonia.PropertyStore
|
||||
IDisposable
|
||||
{
|
||||
private readonly ValueStore _owner;
|
||||
private readonly bool _hasDataValidation;
|
||||
private IDisposable? _subscription;
|
||||
|
||||
public DirectUntypedBindingObserver(ValueStore owner, DirectPropertyBase<T> property)
|
||||
{
|
||||
_owner = owner;
|
||||
_hasDataValidation = property.GetMetadata(owner.Owner.GetType())?.EnableDataValidation ?? false;
|
||||
Property = property;
|
||||
}
|
||||
|
||||
@@ -30,6 +32,9 @@ namespace Avalonia.PropertyStore
|
||||
_subscription?.Dispose();
|
||||
_subscription = null;
|
||||
_owner.OnLocalValueBindingCompleted(Property, this);
|
||||
|
||||
if (_hasDataValidation)
|
||||
_owner.Owner.OnUpdateDataValidation(Property, BindingValueType.UnsetValue, null);
|
||||
}
|
||||
|
||||
public void OnCompleted() => _owner.OnLocalValueBindingCompleted(Property, this);
|
||||
|
||||
@@ -37,10 +37,17 @@ namespace Avalonia.PropertyStore
|
||||
{
|
||||
_subscription?.Dispose();
|
||||
_subscription = null;
|
||||
OnCompleted();
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
if (_hasDataValidation)
|
||||
_owner.Owner.OnUpdateDataValidation(Property, BindingValueType.UnsetValue, null);
|
||||
|
||||
_owner.OnLocalValueBindingCompleted(Property, this);
|
||||
}
|
||||
|
||||
public void OnCompleted() => _owner.OnLocalValueBindingCompleted(Property, this);
|
||||
public void OnError(Exception error) => OnCompleted();
|
||||
|
||||
public void OnNext(T value)
|
||||
|
||||
@@ -92,6 +92,48 @@ namespace Avalonia.Base.UnitTests
|
||||
Assert.Equal(1, target.Notifications.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Disposing_Binding_Subscription_Clears_DataValidation()
|
||||
{
|
||||
var target = new Class1();
|
||||
var source = new Subject<BindingValue<int>>();
|
||||
var property = GetProperty();
|
||||
var error = new Exception();
|
||||
var sub = target.Bind(property, source);
|
||||
|
||||
source.OnNext(6);
|
||||
source.OnNext(BindingValue<int>.DataValidationError(error));
|
||||
sub.Dispose();
|
||||
|
||||
Assert.Equal(new Notification[]
|
||||
{
|
||||
new(BindingValueType.Value, 6, null),
|
||||
new(BindingValueType.DataValidationError, 6, error),
|
||||
new(BindingValueType.UnsetValue, 6, null),
|
||||
}, target.Notifications);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Completing_Binding_Clears_DataValidation()
|
||||
{
|
||||
var target = new Class1();
|
||||
var source = new Subject<BindingValue<int>>();
|
||||
var property = GetProperty();
|
||||
var error = new Exception();
|
||||
|
||||
target.Bind(property, source);
|
||||
source.OnNext(6);
|
||||
source.OnNext(BindingValue<int>.DataValidationError(error));
|
||||
source.OnCompleted();
|
||||
|
||||
Assert.Equal(new Notification[]
|
||||
{
|
||||
new(BindingValueType.Value, 6, null),
|
||||
new(BindingValueType.DataValidationError, 6, error),
|
||||
new(BindingValueType.UnsetValue, 6, null),
|
||||
}, target.Notifications);
|
||||
}
|
||||
|
||||
protected abstract T GetProperty();
|
||||
protected abstract T GetNonValidatedProperty();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,30 @@ namespace Avalonia.Markup.UnitTests.Data
|
||||
Assert.Null(target.DataValidationError);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Disposing_Binding_Subscription_Clears_DataValidation()
|
||||
{
|
||||
var (target, property) = CreateTarget();
|
||||
var binding = new Binding(nameof(ExceptionValidatingModel.Value))
|
||||
{
|
||||
Mode = BindingMode.TwoWay
|
||||
};
|
||||
|
||||
target.DataContext = new IndeiValidatingModel
|
||||
{
|
||||
Value = 200,
|
||||
};
|
||||
|
||||
var sub = target.Bind(property, binding);
|
||||
|
||||
Assert.Equal(200, target.GetValue(property));
|
||||
Assert.IsType<DataValidationException>(target.DataValidationError);
|
||||
|
||||
sub.Dispose();
|
||||
|
||||
Assert.Null(target.DataValidationError);
|
||||
}
|
||||
|
||||
private protected abstract (DataValidationTestControl, T) CreateTarget();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user