Browse Source

Move fix up to PropertyAccessorNode from InpcPropertyAccessorPlugin.

pull/1643/head
Jeremy Koritzinsky 8 years ago
parent
commit
41b20f63f0
  1. 22
      src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
  2. 37
      src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs

22
src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs

@ -52,11 +52,9 @@ namespace Avalonia.Data.Core.Plugins
private class Accessor : PropertyAccessorBase, IWeakSubscriber<PropertyChangedEventArgs>
{
private static readonly object CacheInvalid = new object();
private readonly WeakReference _reference;
private readonly PropertyInfo _property;
private bool _eventRaised;
private object _lastValue = CacheInvalid;
public Accessor(WeakReference reference, PropertyInfo property)
{
@ -74,7 +72,7 @@ namespace Avalonia.Data.Core.Plugins
get
{
var o = _reference.Target;
return (_lastValue = (o != null) ? _property.GetValue(o) : null);
return (o != null) ? _property.GetValue(o) : null;
}
}
@ -82,11 +80,6 @@ namespace Avalonia.Data.Core.Plugins
{
if (_property.CanWrite)
{
if (!ShouldSet(value))
{
return true;
}
_eventRaised = false;
_property.SetValue(_reference.Target, value);
@ -101,24 +94,11 @@ namespace Avalonia.Data.Core.Plugins
return false;
}
private bool ShouldSet(object value)
{
if (PropertyType.IsValueType)
{
return !_lastValue.Equals(value);
}
else
{
return !Object.ReferenceEquals(_lastValue, value);
}
}
void IWeakSubscriber<PropertyChangedEventArgs>.OnEvent(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == _property.Name || string.IsNullOrEmpty(e.PropertyName))
{
_eventRaised = true;
_lastValue = CacheInvalid;
SendCurrentValue();
}
}

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

@ -12,8 +12,10 @@ namespace Avalonia.Data.Core
{
internal class PropertyAccessorNode : ExpressionNode, ISettableNode
{
private static readonly object CacheInvalid = new object();
private readonly bool _enableValidation;
private IPropertyAccessor _accessor;
private object _lastValue = CacheInvalid;
public PropertyAccessorNode(string propertyName, bool enableValidation)
{
@ -29,12 +31,32 @@ namespace Avalonia.Data.Core
{
if (_accessor != null)
{
try { return _accessor.SetValue(value, priority); } catch { }
try
{
if (ShouldNotSet(value))
{
return true;
}
else
{
return _accessor.SetValue(value, priority);
}
}
catch { }
}
return false;
}
private bool ShouldNotSet(object value)
{
if (PropertyType.IsValueType)
{
return _lastValue.Equals(value);
}
return Object.ReferenceEquals(_lastValue, value);
}
protected override IObservable<object> StartListeningCore(WeakReference reference)
{
var plugin = ExpressionObserver.PropertyAccessors.FirstOrDefault(x => x.Match(reference.Target, PropertyName));
@ -58,7 +80,18 @@ namespace Avalonia.Data.Core
_accessor = accessor;
return Disposable.Create(() => _accessor = null);
},
_ => accessor);
_ => accessor).Select(value =>
{
if (value is BindingNotification notification)
{
_lastValue = notification.HasValue ? notification.Value : CacheInvalid;
}
else
{
_lastValue = value;
}
return value;
});
}
}
}

Loading…
Cancel
Save