|
|
|
@ -38,22 +38,22 @@ namespace Avalonia.Data |
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the <see cref="IValueConverter"/> to use.
|
|
|
|
/// </summary>
|
|
|
|
public IValueConverter Converter { get; set; } |
|
|
|
public IValueConverter? Converter { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a parameter to pass to <see cref="Converter"/>.
|
|
|
|
/// </summary>
|
|
|
|
public object ConverterParameter { get; set; } |
|
|
|
public object? ConverterParameter { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the value to use when the binding is unable to produce a value.
|
|
|
|
/// </summary>
|
|
|
|
public object FallbackValue { get; set; } |
|
|
|
public object? FallbackValue { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the value to use when the binding result is null.
|
|
|
|
/// </summary>
|
|
|
|
public object TargetNullValue { get; set; } |
|
|
|
public object? TargetNullValue { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the binding mode.
|
|
|
|
@ -68,23 +68,23 @@ namespace Avalonia.Data |
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the string format.
|
|
|
|
/// </summary>
|
|
|
|
public string StringFormat { get; set; } |
|
|
|
public string? StringFormat { get; set; } |
|
|
|
|
|
|
|
public WeakReference DefaultAnchor { get; set; } |
|
|
|
public WeakReference? DefaultAnchor { get; set; } |
|
|
|
|
|
|
|
public WeakReference<INameScope> NameScope { get; set; } |
|
|
|
public WeakReference<INameScope>? NameScope { get; set; } |
|
|
|
|
|
|
|
protected abstract ExpressionObserver CreateExpressionObserver( |
|
|
|
IAvaloniaObject target, |
|
|
|
AvaloniaProperty targetProperty, |
|
|
|
object anchor, |
|
|
|
object? anchor, |
|
|
|
bool enableDataValidation); |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public InstancedBinding Initiate( |
|
|
|
IAvaloniaObject target, |
|
|
|
AvaloniaProperty targetProperty, |
|
|
|
object anchor = null, |
|
|
|
object? anchor = null, |
|
|
|
bool enableDataValidation = false) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(target != null); |
|
|
|
@ -133,18 +133,13 @@ namespace Avalonia.Data |
|
|
|
IAvaloniaObject target, |
|
|
|
ExpressionNode node, |
|
|
|
bool targetIsDataContext, |
|
|
|
object anchor) |
|
|
|
object? anchor) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(target != null); |
|
|
|
|
|
|
|
if (!(target is IDataContextProvider)) |
|
|
|
{ |
|
|
|
target = anchor as IDataContextProvider; |
|
|
|
|
|
|
|
if (target == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("Cannot find a DataContext to bind to."); |
|
|
|
} |
|
|
|
target = anchor as IDataContextProvider ?? throw new InvalidOperationException("Cannot find a DataContext to bind to."); |
|
|
|
} |
|
|
|
|
|
|
|
if (!targetIsDataContext) |
|
|
|
@ -173,8 +168,7 @@ namespace Avalonia.Data |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(target != null); |
|
|
|
|
|
|
|
NameScope.TryGetTarget(out var scope); |
|
|
|
if (scope == null) |
|
|
|
if (NameScope is null || !NameScope.TryGetTarget(out var scope) || scope is null) |
|
|
|
throw new InvalidOperationException("Name scope is null or was already collected"); |
|
|
|
var result = new ExpressionObserver( |
|
|
|
NameScopeLocator.Track(scope, elementName), |
|
|
|
@ -190,7 +184,7 @@ namespace Avalonia.Data |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(target != null); |
|
|
|
|
|
|
|
IObservable<object> controlLocator; |
|
|
|
IObservable<object?> controlLocator; |
|
|
|
|
|
|
|
switch (relativeSource.Tree) |
|
|
|
{ |
|
|
|
@ -229,7 +223,7 @@ namespace Avalonia.Data |
|
|
|
IAvaloniaObject target, |
|
|
|
ExpressionNode node) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(target != null); |
|
|
|
Contract.Requires<ArgumentNullException>(target is not null); |
|
|
|
|
|
|
|
var result = new ExpressionObserver( |
|
|
|
() => target.GetValue(StyledElement.TemplatedParentProperty), |
|
|
|
@ -240,7 +234,7 @@ namespace Avalonia.Data |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
protected IObservable<object> GetParentDataContext(IAvaloniaObject target) |
|
|
|
protected IObservable<object?> GetParentDataContext(IAvaloniaObject target) |
|
|
|
{ |
|
|
|
// The DataContext is based on the visual parent and not the logical parent: this may
|
|
|
|
// seem counter intuitive considering the fact that property inheritance works on the logical
|
|
|
|
@ -252,7 +246,7 @@ namespace Avalonia.Data |
|
|
|
.Select(x => |
|
|
|
{ |
|
|
|
return (x as IAvaloniaObject)?.GetObservable(StyledElement.DataContextProperty) ?? |
|
|
|
Observable.Return((object)null); |
|
|
|
Observable.Return((object?)null); |
|
|
|
}).Switch(); |
|
|
|
} |
|
|
|
|
|
|
|
|