20 changed files with 212 additions and 90 deletions
@ -1,10 +1,31 @@ |
|||
using Avalonia.Styling; |
|||
using Avalonia.PropertyStore; |
|||
using Avalonia.Styling; |
|||
|
|||
namespace Avalonia.Data.Core; |
|||
|
|||
public abstract class BindingExpressionBase : ISetterInstance |
|||
public abstract class BindingExpressionBase : IBindingExpression, ISetterInstance |
|||
{ |
|||
private protected BindingExpressionBase() |
|||
{ |
|||
} |
|||
|
|||
internal BindingMode Mode { get; private protected set; } |
|||
|
|||
public virtual void Dispose() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// When overridden in a derived class, attaches the binding expression to a value store but
|
|||
/// does not start it.
|
|||
/// </summary>
|
|||
/// <param name="valueStore">The value store to attach to.</param>
|
|||
/// <param name="target">The target object.</param>
|
|||
/// <param name="targetProperty">The target property.</param>
|
|||
/// <param name="priority">The priority of the binding.</param>
|
|||
internal abstract void Attach( |
|||
ValueStore valueStore, |
|||
AvaloniaObject target, |
|||
AvaloniaProperty targetProperty, |
|||
BindingPriority priority); |
|||
} |
|||
|
|||
@ -0,0 +1,99 @@ |
|||
using Avalonia.Controls; |
|||
using Avalonia.Data; |
|||
using Avalonia.Data.Core; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Base.UnitTests.Data.Core |
|||
{ |
|||
[InvariantCulture] |
|||
public class BindingExpressionTests_Mode |
|||
{ |
|||
[Fact] |
|||
public void OneTime_Binding_Sets_Target_Only_Once() |
|||
{ |
|||
var data = new ViewModel(); |
|||
var binding = new Binding(nameof(data.Foo), BindingMode.OneTime); |
|||
var target = new Control { DataContext = data }; |
|||
|
|||
target.Bind(Control.TagProperty, binding); |
|||
Assert.Equal("foo", target.Tag); |
|||
|
|||
data.Foo = "bar"; |
|||
Assert.Equal("foo", target.Tag); |
|||
} |
|||
|
|||
[Fact] |
|||
public void OneTime_Binding_Waits_For_DataContext() |
|||
{ |
|||
var data = new ViewModel(); |
|||
var binding = new Binding(nameof(data.Foo), BindingMode.OneTime); |
|||
var target = new Control(); |
|||
|
|||
target.Bind(Control.TagProperty, binding); |
|||
Assert.Null(target.Tag); |
|||
|
|||
target.DataContext = data; |
|||
Assert.Equal("foo", target.Tag); |
|||
|
|||
data.Foo = "bar"; |
|||
Assert.Equal("foo", target.Tag); |
|||
} |
|||
|
|||
[Fact] |
|||
public void OneTime_Binding_Waits_For_DataContext_With_Matching_Property_Name() |
|||
{ |
|||
var data1 = new { Baz = "baz" }; |
|||
var data2 = new ViewModel(); |
|||
var binding = new Binding(nameof(data2.Foo), BindingMode.OneTime); |
|||
var target = new Control { DataContext = data1 }; |
|||
|
|||
target.Bind(Control.TagProperty, binding); |
|||
Assert.Null(target.Tag); |
|||
|
|||
target.DataContext = data2; |
|||
Assert.Equal("foo", target.Tag); |
|||
|
|||
data2.Foo = "bar"; |
|||
Assert.Equal("foo", target.Tag); |
|||
} |
|||
|
|||
private class ViewModel : NotifyingBase |
|||
{ |
|||
private string _foo; |
|||
private double _bar; |
|||
|
|||
public ViewModel(string foo = "foo", double bar = 0.5) |
|||
{ |
|||
_foo = foo; |
|||
_bar = bar; |
|||
} |
|||
|
|||
public string Foo |
|||
{ |
|||
get => _foo; |
|||
set |
|||
{ |
|||
if (_foo != value) |
|||
{ |
|||
_foo = value; |
|||
RaisePropertyChanged(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public double Bar |
|||
{ |
|||
get => _bar; |
|||
set |
|||
{ |
|||
if (_bar != value) |
|||
{ |
|||
_bar = value; |
|||
RaisePropertyChanged(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue