Browse Source

Added typed AvaloniaProperty<T>.Changed.

pull/4648/head
José Pedro 5 years ago
parent
commit
7782261ec3
No known key found for this signature in database GPG Key ID: B8247B9301707B83
  1. 3
      src/Avalonia.Base/ApiCompatBaseline.txt
  2. 17
      src/Avalonia.Base/AvaloniaProperty.cs
  3. 27
      src/Avalonia.Base/AvaloniaProperty`1.cs
  4. 4
      src/Avalonia.Controls/Mixins/SelectableMixin.cs
  5. 2
      src/Avalonia.Controls/NativeMenu.Export.cs
  6. 2
      src/Avalonia.Controls/NativeMenuItem.cs
  7. 2
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  8. 2
      src/Avalonia.Controls/TextBlock.cs
  9. 2
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Direct.cs
  10. 4
      tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs

3
src/Avalonia.Base/ApiCompatBaseline.txt

@ -0,0 +1,3 @@
Compat issues with assembly Avalonia.Base:
CannotAddAbstractMembers : Member 'protected System.IObservable<Avalonia.AvaloniaPropertyChangedEventArgs> Avalonia.AvaloniaProperty.GetChanged()' is abstract in the implementation but is missing in the contract.
Total Issues: 1

17
src/Avalonia.Base/AvaloniaProperty.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Reactive.Subjects;
using Avalonia.Data;
using Avalonia.Data.Core;
using Avalonia.Utilities;
@ -18,7 +17,6 @@ namespace Avalonia
public static readonly object UnsetValue = new UnsetValueType();
private static int s_nextId;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _changed;
private readonly PropertyMetadata _defaultMetadata;
private readonly Dictionary<Type, PropertyMetadata> _metadata;
private readonly Dictionary<Type, PropertyMetadata> _metadataCache = new Dictionary<Type, PropertyMetadata>();
@ -50,7 +48,6 @@ namespace Avalonia
throw new ArgumentException("'name' may not contain periods.");
}
_changed = new Subject<AvaloniaPropertyChangedEventArgs>();
_metadata = new Dictionary<Type, PropertyMetadata>();
Name = name;
@ -77,7 +74,6 @@ namespace Avalonia
Contract.Requires<ArgumentNullException>(source != null);
Contract.Requires<ArgumentNullException>(ownerType != null);
_changed = source._changed;
_metadata = new Dictionary<Type, PropertyMetadata>();
Name = source.Name;
@ -139,7 +135,7 @@ namespace Avalonia
/// An observable that is fired when this property changes on any
/// <see cref="AvaloniaObject"/> instance.
/// </value>
public IObservable<AvaloniaPropertyChangedEventArgs> Changed => _changed;
public IObservable<AvaloniaPropertyChangedEventArgs> Changed => GetChanged();
/// <summary>
/// Gets a method that gets called before and after the property starts being notified on an
@ -474,15 +470,6 @@ namespace Avalonia
public abstract void Accept<TData>(IAvaloniaPropertyVisitor<TData> vistor, ref TData data)
where TData : struct;
/// <summary>
/// Notifies the <see cref="Changed"/> observable.
/// </summary>
/// <param name="e">The observable arguments.</param>
internal void NotifyChanged(AvaloniaPropertyChangedEventArgs e)
{
_changed.OnNext(e);
}
/// <summary>
/// Routes an untyped ClearValue call to a typed call.
/// </summary>
@ -553,6 +540,8 @@ namespace Avalonia
_hasMetadataOverrides = true;
}
protected abstract IObservable<AvaloniaPropertyChangedEventArgs> GetChanged();
private PropertyMetadata GetMetadataWithOverrides(Type type)
{
if (type is null)

27
src/Avalonia.Base/AvaloniaProperty`1.cs

@ -1,4 +1,5 @@
using System;
using System.Reactive.Subjects;
using Avalonia.Data;
using Avalonia.Utilities;
@ -10,6 +11,8 @@ namespace Avalonia
/// <typeparam name="TValue">The value type of the property.</typeparam>
public abstract class AvaloniaProperty<TValue> : AvaloniaProperty
{
private readonly Subject<AvaloniaPropertyChangedEventArgs<TValue>> _changed;
/// <summary>
/// Initializes a new instance of the <see cref="AvaloniaProperty{TValue}"/> class.
/// </summary>
@ -24,6 +27,7 @@ namespace Avalonia
Action<IAvaloniaObject, bool> notifying = null)
: base(name, typeof(TValue), ownerType, metadata, notifying)
{
_changed = new Subject<AvaloniaPropertyChangedEventArgs<TValue>>();
}
/// <summary>
@ -38,8 +42,31 @@ namespace Avalonia
PropertyMetadata metadata)
: base(source, ownerType, metadata)
{
_changed = source is AvaloniaProperty<TValue> p ? p._changed : new Subject<AvaloniaPropertyChangedEventArgs<TValue>>();
}
/// <summary>
/// Gets an observable that is fired when this property changes on any
/// <see cref="AvaloniaObject"/> instance.
/// </summary>
/// <value>
/// An observable that is fired when this property changes on any
/// <see cref="AvaloniaObject"/> instance.
/// </value>
public new IObservable<AvaloniaPropertyChangedEventArgs<TValue>> Changed => _changed;
/// <summary>
/// Notifies the <see cref="Changed"/> observable.
/// </summary>
/// <param name="e">The observable arguments.</param>
internal void NotifyChanged(AvaloniaPropertyChangedEventArgs<TValue> e)
{
_changed.OnNext(e);
}
protected override IObservable<AvaloniaPropertyChangedEventArgs> GetChanged() => Changed;
protected BindingValue<object> TryConvert(object value)
{
if (value == UnsetValue)

4
src/Avalonia.Controls/Mixins/SelectableMixin.cs

@ -42,7 +42,7 @@ namespace Avalonia.Controls.Mixins
{
Contract.Requires<ArgumentNullException>(isSelected != null);
isSelected.Changed.Subscribe(x =>
isSelected.Changed.Subscribe((AvaloniaPropertyChangedEventArgs x) =>
{
var sender = x.Sender as TControl;
@ -58,4 +58,4 @@ namespace Avalonia.Controls.Mixins
});
}
}
}
}

2
src/Avalonia.Controls/NativeMenu.Export.cs

@ -73,7 +73,7 @@ namespace Avalonia.Controls
throw new InvalidOperationException("IsNativeMenuExported property is read-only");
info.ChangingIsExported = false;
});
MenuProperty.Changed.Subscribe(args =>
MenuProperty.Changed.Subscribe((AvaloniaPropertyChangedEventArgs args) =>
{
if (args.Sender is TopLevel tl)
{

2
src/Avalonia.Controls/NativeMenuItem.cs

@ -20,7 +20,7 @@ namespace Avalonia.Controls
static NativeMenuItem()
{
MenuProperty.Changed.Subscribe(args =>
MenuProperty.Changed.Subscribe((AvaloniaPropertyChangedEventArgs args) =>
{
var item = (NativeMenuItem)args.Sender;
var value = (NativeMenu)args.NewValue;

2
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -82,7 +82,7 @@ namespace Avalonia.Controls.Presenters
TextAlignmentProperty, TextWrappingProperty, TextBlock.FontSizeProperty,
TextBlock.FontStyleProperty, TextBlock.FontWeightProperty, TextBlock.FontFamilyProperty);
Observable.Merge(TextProperty.Changed, TextBlock.ForegroundProperty.Changed,
Observable.Merge<AvaloniaPropertyChangedEventArgs>(TextProperty.Changed, TextBlock.ForegroundProperty.Changed,
TextAlignmentProperty.Changed, TextWrappingProperty.Changed,
TextBlock.FontSizeProperty.Changed, TextBlock.FontStyleProperty.Changed,
TextBlock.FontWeightProperty.Changed, TextBlock.FontFamilyProperty.Changed,

2
src/Avalonia.Controls/TextBlock.cs

@ -138,7 +138,7 @@ namespace Avalonia.Controls
FontStyleProperty, TextWrappingProperty, FontFamilyProperty,
TextTrimmingProperty, TextProperty, PaddingProperty, LineHeightProperty, MaxLinesProperty);
Observable.Merge(TextProperty.Changed, ForegroundProperty.Changed,
Observable.Merge<AvaloniaPropertyChangedEventArgs>(TextProperty.Changed, ForegroundProperty.Changed,
TextAlignmentProperty.Changed, TextWrappingProperty.Changed,
TextTrimmingProperty.Changed, FontSizeProperty.Changed,
FontStyleProperty.Changed, FontWeightProperty.Changed,

2
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Direct.cs

@ -92,7 +92,7 @@ namespace Avalonia.Base.UnitTests
var target = new Class1();
bool raised = false;
Class1.FooProperty.Changed.Subscribe(e =>
Class1.FooProperty.Changed.Subscribe((AvaloniaPropertyChangedEventArgs e) =>
raised = e.Property == Class1.FooProperty &&
(string)e.OldValue == "initial" &&
(string)e.NewValue == "newvalue" &&

4
tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs

@ -83,7 +83,7 @@ namespace Avalonia.Base.UnitTests
var target = new Class1();
string value = null;
Class1.FooProperty.Changed.Subscribe(x => value = (string)x.NewValue);
Class1.FooProperty.Changed.Subscribe((AvaloniaPropertyChangedEventArgs x) => value = (string)x.NewValue);
target.SetValue(Class1.FooProperty, "newvalue");
Assert.Equal("newvalue", value);
@ -95,7 +95,7 @@ namespace Avalonia.Base.UnitTests
var target = new Class1();
var result = new List<string>();
Class1.FooProperty.Changed.Subscribe(x => result.Add((string)x.NewValue));
Class1.FooProperty.Changed.Subscribe((AvaloniaPropertyChangedEventArgs x) => result.Add((string)x.NewValue));
target.SetValue(Class1.FooProperty, "animated", BindingPriority.Animation);
target.SetValue(Class1.FooProperty, "local");

Loading…
Cancel
Save