Browse Source

Correctly handle default values in batch update notifications.

We were previously calling `Optional.GetValueOrDefault<T>()` in order to convert an `Optional<object>` to an `Optional<T>` which meant that empty values were getting converted to default values, meaning that in certain cases change notifications weren't raised.

Add an `Optional<object>.Cast<T>()` methods (like we have in `BindingValue`) and use that in order to preserve empty values when ending a batch update operation.
pull/5852/head
Steven Kirk 5 years ago
parent
commit
8959d55418
  1. 14
      src/Avalonia.Base/Data/Optional.cs
  2. 4
      src/Avalonia.Base/PropertyStore/BindingEntry.cs
  3. 4
      src/Avalonia.Base/PropertyStore/ConstantValueEntry.cs
  4. 4
      src/Avalonia.Base/PropertyStore/LocalValueEntry.cs
  5. 4
      src/Avalonia.Base/PropertyStore/PriorityValue.cs

14
src/Avalonia.Base/Data/Optional.cs

@ -153,4 +153,18 @@ namespace Avalonia.Data
/// </summary>
public static Optional<T> Empty => default;
}
public static class OptionalExtensions
{
/// <summary>
/// Casts the type of an <see cref="Optional{T}"/> using only the C# cast operator.
/// </summary>
/// <typeparam name="T">The target type.</typeparam>
/// <param name="value">The binding value.</param>
/// <returns>The cast value.</returns>
public static Optional<T> Cast<T>(this Optional<object> value)
{
return value.HasValue ? new Optional<T>((T)value.Value) : Optional<T>.Empty;
}
}
}

4
src/Avalonia.Base/PropertyStore/BindingEntry.cs

@ -127,8 +127,8 @@ namespace Avalonia.PropertyStore
sink.ValueChanged(new AvaloniaPropertyChangedEventArgs<T>(
owner,
(AvaloniaProperty<T>)property,
oldValue.GetValueOrDefault<T>(),
newValue.GetValueOrDefault<T>(),
oldValue.Cast<T>(),
newValue.Cast<T>(),
Priority));
}

4
src/Avalonia.Base/PropertyStore/ConstantValueEntry.cs

@ -65,8 +65,8 @@ namespace Avalonia.PropertyStore
sink.ValueChanged(new AvaloniaPropertyChangedEventArgs<T>(
owner,
(AvaloniaProperty<T>)property,
oldValue.GetValueOrDefault<T>(),
newValue.GetValueOrDefault<T>(),
oldValue.Cast<T>(),
newValue.Cast<T>(),
Priority));
}
}

4
src/Avalonia.Base/PropertyStore/LocalValueEntry.cs

@ -36,8 +36,8 @@ namespace Avalonia.PropertyStore
sink.ValueChanged(new AvaloniaPropertyChangedEventArgs<T>(
owner,
(AvaloniaProperty<T>)property,
oldValue.GetValueOrDefault<T>(),
newValue.GetValueOrDefault<T>(),
oldValue.Cast<T>(),
newValue.Cast<T>(),
BindingPriority.LocalValue));
}
}

4
src/Avalonia.Base/PropertyStore/PriorityValue.cs

@ -197,8 +197,8 @@ namespace Avalonia.PropertyStore
sink.ValueChanged(new AvaloniaPropertyChangedEventArgs<T>(
owner,
(AvaloniaProperty<T>)property,
oldValue.GetValueOrDefault<T>(),
newValue.GetValueOrDefault<T>(),
oldValue.Cast<T>(),
newValue.Cast<T>(),
Priority));
}

Loading…
Cancel
Save