diff --git a/src/Avalonia.Base/PriorityValue.cs b/src/Avalonia.Base/PriorityValue.cs
index df138c88f5..3930b6c224 100644
--- a/src/Avalonia.Base/PriorityValue.cs
+++ b/src/Avalonia.Base/PriorityValue.cs
@@ -235,75 +235,56 @@ namespace Avalonia
/// The priority level that the value came from.
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));
}
}
}
diff --git a/src/Avalonia.Base/Utilities/DelayedSetter.cs b/src/Avalonia.Base/Utilities/DelayedSetter.cs
index 6d611dfa46..155e4509a2 100644
--- a/src/Avalonia.Base/Utilities/DelayedSetter.cs
+++ b/src/Avalonia.Base/Utilities/DelayedSetter.cs
@@ -58,7 +58,7 @@ namespace Avalonia.Utilities
return setRecords[property].PendingValues.Dequeue();
}
- public void SetAndNotify(T property, Action> setterCallback, TValue value)
+ public void SetAndNotify(T property, Action> setterCallback, TValue value, Predicate pendingSetCondition)
{
Contract.Requires(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> setterCallback, TValue value)
+ => SetAndNotify(property, setterCallback, value, null);
}
}