Browse Source

Have PriorityValue use SetAndNotify infrastructure.

pull/856/head
Jeremy Koritzinsky 9 years ago
parent
commit
36fe461b4a
  1. 89
      src/Avalonia.Base/PriorityValue.cs
  2. 7
      src/Avalonia.Base/Utilities/DelayedSetter.cs

89
src/Avalonia.Base/PriorityValue.cs

@ -235,75 +235,56 @@ namespace Avalonia
/// <param name="priority">The priority level that the value came from.</param>
private void UpdateValue(object value, int priority)
{
if (!delayedSetter.IsNotifying(this))
delayedSetter.SetAndNotify(this, (update, notify) =>
{
value = UpdateValueCore(value, priority);
var val = update.value;
var notification = val as BindingNotification;
object castValue;
while (delayedSetter.HasPendingSet(this))
if (notification != null)
{
var pendingSet = delayedSetter.GetFirstPendingSet(this);
UpdateValueCore(pendingSet.value, pendingSet.priority);
val = (notification.HasValue) ? notification.Value : null;
}
}
else if(!object.Equals(value, _value))
{
delayedSetter.AddPendingSet(this, (value, priority));
}
}
private object UpdateValueCore(object value, int priority)
{
var notification = value as BindingNotification;
object castValue;
if (notification != null)
{
value = (notification.HasValue) ? notification.Value : null;
}
if (TypeUtilities.TryConvertImplicit(_valueType, val, out castValue))
{
var old = _value;
if (TypeUtilities.TryConvertImplicit(_valueType, value, out castValue))
{
var old = _value;
if (_validate != null && castValue != AvaloniaProperty.UnsetValue)
{
castValue = _validate(castValue);
}
if (_validate != null && castValue != AvaloniaProperty.UnsetValue)
{
castValue = _validate(castValue);
}
ValuePriority = priority;
_value = castValue;
ValuePriority = priority;
_value = castValue;
if (notification?.HasValue == true)
{
notification.SetValue(castValue);
}
if (notification?.HasValue == true)
{
notification.SetValue(castValue);
}
if (notification == null || notification.HasValue)
{
notify(() => Owner?.Changed(this, old, _value));
}
if (notification == null || notification.HasValue)
{
using (delayedSetter.MarkNotifying(this))
if (notification != null)
{
Owner?.Changed(this, old, _value);
Owner?.BindingNotificationReceived(this, notification);
}
}
if (notification != null)
else
{
Owner?.BindingNotificationReceived(this, notification);
Logger.Error(
LogArea.Binding,
Owner,
"Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})",
Property.Name,
_valueType,
val,
val?.GetType());
}
}
else
{
Logger.Error(
LogArea.Binding,
Owner,
"Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})",
Property.Name,
_valueType,
value,
value?.GetType());
}
return value;
}, (value, priority), val => !object.Equals(val.value, _value));
}
}
}

7
src/Avalonia.Base/Utilities/DelayedSetter.cs

@ -58,7 +58,7 @@ namespace Avalonia.Utilities
return setRecords[property].PendingValues.Dequeue();
}
public void SetAndNotify(T property, Action<TValue, Action<Action>> setterCallback, TValue value)
public void SetAndNotify(T property, Action<TValue, Action<Action>> setterCallback, TValue value, Predicate<TValue> pendingSetCondition)
{
Contract.Requires<ArgumentNullException>(setterCallback != null);
if (!IsNotifying(property))
@ -81,10 +81,13 @@ namespace Avalonia.Utilities
});
}
}
else
else if(pendingSetCondition?.Invoke(value) ?? true)
{
AddPendingSet(property, value);
}
}
public void SetAndNotify(T property, Action<TValue, Action<Action>> setterCallback, TValue value)
=> SetAndNotify(property, setterCallback, value, null);
}
}

Loading…
Cancel
Save