Browse Source

Merge pull request #4150 from MarchingCube/fix-validation-not-found-member

Fix validation of not found members
pull/4164/head
Steven Kirk 6 years ago
committed by GitHub
parent
commit
fabba53b41
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs
  2. 22
      tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs

23
src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
namespace Avalonia.Data.Core namespace Avalonia.Data.Core
@ -49,6 +50,18 @@ namespace Avalonia.Data.Core
var accessor = plugin?.Start(reference, PropertyName); var accessor = plugin?.Start(reference, PropertyName);
// We need to handle accessor fallback before handling validation. Validators do not support null accessors.
if (accessor == null)
{
reference.TryGetTarget(out object instance);
var message = $"Could not find a matching property accessor for '{PropertyName}' on '{instance}'";
var exception = new MissingMemberException(message);
accessor = new PropertyError(new BindingNotification(exception, BindingErrorType.Error));
}
if (_enableValidation && Next == null) if (_enableValidation && Next == null)
{ {
foreach (var validator in ExpressionObserver.DataValidators) foreach (var validator in ExpressionObserver.DataValidators)
@ -60,15 +73,9 @@ namespace Avalonia.Data.Core
} }
} }
if (accessor == null) if (accessor is null)
{ {
reference.TryGetTarget(out object instance); throw new AvaloniaInternalException("Data validators must return non-null accessor.");
var message = $"Could not find a matching property accessor for '{PropertyName}' on '{instance}'";
var exception = new MissingMemberException(message);
accessor = new PropertyError(new BindingNotification(exception, BindingErrorType.Error));
} }
_accessor = accessor; _accessor = accessor;

22
tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs

@ -578,6 +578,28 @@ namespace Avalonia.Base.UnitTests.Data.Core
Assert.True(true); Assert.True(true);
} }
[Fact]
public void Should_Not_Throw_Exception_When_Enabling_Data_Validation_On_Missing_Member()
{
var source = new Class1();
var target = new PropertyAccessorNode("NotFound", true);
target.Target = new WeakReference<object>(source);
var result = new List<object>();
target.Subscribe(x => result.Add(x));
Assert.Equal(
new object[]
{
new BindingNotification(
new MissingMemberException("Could not find a matching property accessor for 'NotFound' on 'Avalonia.Base.UnitTests.Data.Core.ExpressionObserverTests_Property+Class1'"),
BindingErrorType.Error),
},
result);
}
private interface INext private interface INext
{ {
int PropertyChangedSubscriptionCount { get; } int PropertyChangedSubscriptionCount { get; }

Loading…
Cancel
Save