|
|
|
@ -101,6 +101,7 @@ namespace Avalonia.Controls |
|
|
|
private Styles _styles; |
|
|
|
private bool _styled; |
|
|
|
private Subject<IStyleable> _styleDetach = new Subject<IStyleable>(); |
|
|
|
private bool _dataContextUpdating; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes static members of the <see cref="Control"/> class.
|
|
|
|
@ -111,6 +112,7 @@ namespace Avalonia.Controls |
|
|
|
PseudoClass(IsEnabledCoreProperty, x => !x, ":disabled"); |
|
|
|
PseudoClass(IsFocusedProperty, ":focus"); |
|
|
|
PseudoClass(IsPointerOverProperty, ":pointerover"); |
|
|
|
DataContextProperty.Changed.AddClassHandler<Control>(x => x.OnDataContextChangedCore); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -681,18 +683,26 @@ namespace Avalonia.Controls |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called before the <see cref="DataContext"/> property changes.
|
|
|
|
/// Called when the <see cref="DataContext"/> property changes.
|
|
|
|
/// </summary>
|
|
|
|
protected virtual void OnDataContextChanging() |
|
|
|
/// <param name="e">The event args.</param>
|
|
|
|
protected virtual void OnDataContextChanged(EventArgs e) |
|
|
|
{ |
|
|
|
DataContextChanged?.Invoke(this, EventArgs.Empty); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called after the <see cref="DataContext"/> property changes.
|
|
|
|
/// Called when the <see cref="DataContext"/> begins updating.
|
|
|
|
/// </summary>
|
|
|
|
protected virtual void OnDataContextChanged() |
|
|
|
protected virtual void OnDataContextBeginUpdate() |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when the <see cref="DataContext"/> finishes updating.
|
|
|
|
/// </summary>
|
|
|
|
protected virtual void OnDataContextEndUpdate() |
|
|
|
{ |
|
|
|
DataContextChanged?.Invoke(this, EventArgs.Empty); |
|
|
|
} |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
@ -745,24 +755,38 @@ namespace Avalonia.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when the <see cref="DataContext"/> property begins and ends being notified.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="o">The object on which the DataContext is changing.</param>
|
|
|
|
/// <param name="notifying">Whether the notifcation is beginning or ending.</param>
|
|
|
|
private static void DataContextNotifying(IAvaloniaObject o, bool notifying) |
|
|
|
{ |
|
|
|
var control = o as Control; |
|
|
|
if (o is Control control) |
|
|
|
{ |
|
|
|
DataContextNotifying(control, notifying); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (control != null) |
|
|
|
private static void DataContextNotifying(Control control, bool notifying) |
|
|
|
{ |
|
|
|
if (notifying) |
|
|
|
{ |
|
|
|
if (notifying) |
|
|
|
if (!control._dataContextUpdating) |
|
|
|
{ |
|
|
|
control.OnDataContextChanging(); |
|
|
|
control._dataContextUpdating = true; |
|
|
|
control.OnDataContextBeginUpdate(); |
|
|
|
|
|
|
|
foreach (var child in control.LogicalChildren) |
|
|
|
{ |
|
|
|
if (child is Control c && !c.IsSet(DataContextProperty)) |
|
|
|
{ |
|
|
|
DataContextNotifying(c, notifying); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (control._dataContextUpdating) |
|
|
|
{ |
|
|
|
control.OnDataContextChanged(); |
|
|
|
control.OnDataContextEndUpdate(); |
|
|
|
control._dataContextUpdating = false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -881,6 +905,11 @@ namespace Avalonia.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void OnDataContextChangedCore(AvaloniaPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
OnDataContextChanged(EventArgs.Empty); |
|
|
|
} |
|
|
|
|
|
|
|
private void LogicalChildrenCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
|
|
|
{ |
|
|
|
switch (e.Action) |
|
|
|
|