csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
5.3 KiB
142 lines
5.3 KiB
// Copyright (c) The Avalonia Project. All rights reserved.
|
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using Avalonia.Data;
|
|
using Xunit;
|
|
|
|
namespace Avalonia.Base.UnitTests
|
|
{
|
|
public class AvaloniaObjectTests_OnPropertyChanged
|
|
{
|
|
[Fact]
|
|
public void OnPropertyChangedCore_Is_Called_On_Property_Change()
|
|
{
|
|
var target = new Class1();
|
|
|
|
target.SetValue(Class1.FooProperty, "newvalue");
|
|
|
|
Assert.Equal(1, target.CoreChanges.Count);
|
|
|
|
var change = (AvaloniaPropertyChangedEventArgs<string>)target.CoreChanges[0];
|
|
|
|
Assert.Equal("newvalue", change.NewValue.Value);
|
|
Assert.Equal("foodefault", change.OldValue.Value);
|
|
Assert.Equal(BindingPriority.LocalValue, change.Priority);
|
|
Assert.True(change.IsEffectiveValueChange);
|
|
}
|
|
|
|
[Fact]
|
|
public void OnPropertyChangedCore_Is_Called_On_Non_Effective_Property_Value_Change()
|
|
{
|
|
var target = new Class1();
|
|
|
|
target.SetValue(Class1.FooProperty, "newvalue");
|
|
target.SetValue(Class1.FooProperty, "styled", BindingPriority.Style);
|
|
|
|
Assert.Equal(2, target.CoreChanges.Count);
|
|
|
|
var change = (AvaloniaPropertyChangedEventArgs<string>)target.CoreChanges[1];
|
|
|
|
Assert.Equal("styled", change.NewValue.Value);
|
|
Assert.False(change.OldValue.HasValue);
|
|
Assert.Equal(BindingPriority.Style, change.Priority);
|
|
Assert.False(change.IsEffectiveValueChange);
|
|
}
|
|
|
|
[Fact]
|
|
public void OnPropertyChangedCore_Is_Called_On_All_Binding_Property_Changes()
|
|
{
|
|
var target = new Class1();
|
|
var style = new Subject<BindingValue<string>>();
|
|
var animation = new Subject<BindingValue<string>>();
|
|
var templatedParent = new Subject<BindingValue<string>>();
|
|
|
|
target.Bind(Class1.FooProperty, style, BindingPriority.Style);
|
|
target.Bind(Class1.FooProperty, animation, BindingPriority.Animation);
|
|
target.Bind(Class1.FooProperty, templatedParent, BindingPriority.TemplatedParent);
|
|
|
|
style.OnNext("style1");
|
|
templatedParent.OnNext("tp1");
|
|
animation.OnNext("a1");
|
|
templatedParent.OnNext("tp2");
|
|
templatedParent.OnCompleted();
|
|
animation.OnNext("a2");
|
|
style.OnNext("style2");
|
|
style.OnCompleted();
|
|
animation.OnCompleted();
|
|
|
|
var changes = target.CoreChanges.Cast<AvaloniaPropertyChangedEventArgs<string>>();
|
|
|
|
Assert.Equal(
|
|
new[] { true, true, true, false, false, true, false, false, true },
|
|
changes.Select(x => x.IsEffectiveValueChange).ToList());
|
|
Assert.Equal(
|
|
new[] { "style1", "tp1", "a1", "tp2", "$unset", "a2", "style2", "$unset", "foodefault" },
|
|
changes.Select(x => x.NewValue.GetValueOrDefault("$unset")).ToList());
|
|
Assert.Equal(
|
|
new[] { "foodefault", "style1", "tp1", "$unset", "$unset", "a1", "$unset", "$unset", "a2" },
|
|
changes.Select(x => x.OldValue.GetValueOrDefault("$unset")).ToList());
|
|
}
|
|
|
|
[Fact]
|
|
public void OnPropertyChanged_Is_Called_Only_For_Effective_Value_Changes()
|
|
{
|
|
var target = new Class1();
|
|
|
|
target.SetValue(Class1.FooProperty, "newvalue");
|
|
target.SetValue(Class1.FooProperty, "styled", BindingPriority.Style);
|
|
|
|
Assert.Equal(1, target.Changes.Count);
|
|
Assert.Equal(2, target.CoreChanges.Count);
|
|
}
|
|
|
|
private class Class1 : AvaloniaObject
|
|
{
|
|
public static readonly StyledProperty<string> FooProperty =
|
|
AvaloniaProperty.Register<Class1, string>("Foo", "foodefault");
|
|
|
|
public Class1()
|
|
{
|
|
Changes = new List<AvaloniaPropertyChangedEventArgs>();
|
|
CoreChanges = new List<AvaloniaPropertyChangedEventArgs>();
|
|
}
|
|
|
|
public List<AvaloniaPropertyChangedEventArgs> Changes { get; }
|
|
public List<AvaloniaPropertyChangedEventArgs> CoreChanges { get; }
|
|
|
|
protected override void OnPropertyChangedCore<T>(AvaloniaPropertyChangedEventArgs<T> change)
|
|
{
|
|
CoreChanges.Add(Clone(change));
|
|
base.OnPropertyChangedCore(change);
|
|
}
|
|
|
|
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
|
|
{
|
|
Changes.Add(Clone(change));
|
|
base.OnPropertyChanged(change);
|
|
}
|
|
|
|
private static AvaloniaPropertyChangedEventArgs<T> Clone<T>(AvaloniaPropertyChangedEventArgs<T> change)
|
|
{
|
|
var result = new AvaloniaPropertyChangedEventArgs<T>(
|
|
change.Sender,
|
|
change.Property,
|
|
change.OldValue,
|
|
change.NewValue,
|
|
change.Priority);
|
|
|
|
if (!change.IsEffectiveValueChange)
|
|
{
|
|
result.MarkNonEffectiveValue();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|