Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions src/Controls/src/Core/BindableObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public BindableObject()
}

internal ushort _triggerCount = 0;
internal Dictionary<TriggerBase, SetterSpecificity> _triggerSpecificity = new Dictionary<TriggerBase, SetterSpecificity>();
internal Dictionary<TriggerBase, SetterSpecificity> _triggerSpecificity;
readonly Dictionary<BindableProperty, BindablePropertyContext> _properties = new Dictionary<BindableProperty, BindablePropertyContext>(4);
bool _applying;
WeakReference _inheritedContext;
Expand Down Expand Up @@ -139,7 +139,7 @@ void ClearValueCore(BindableProperty property, SetterSpecificity specificity)
if (changed)
{
property.PropertyChanging?.Invoke(this, original.Value, newValue);
OnPropertyChanging(property.PropertyName);
OnPropertyChanging(property.GetPropertyChangingEventArgs());
}

bpcontext.Values.Remove(specificity);
Expand Down Expand Up @@ -363,7 +363,10 @@ public static void SetInheritedBindingContext(BindableObject bindable, object va
}
else
{
bindable._inheritedContext = new WeakReference(value);
if (bindable._inheritedContext is not null)
bindable._inheritedContext.Target = value;
else
bindable._inheritedContext = new WeakReference(value);
bindable.ApplyBindings(fromBindingContextChanged: true);
bindable.OnBindingContextChanged();
}
Expand Down Expand Up @@ -407,13 +410,27 @@ protected virtual void OnBindingContextChanged()
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

/// <summary>
/// Raises the <see cref="PropertyChanged"/> event using a cached PropertyChangedEventArgs.
/// </summary>
/// <param name="args">The cached PropertyChangedEventArgs to use.</param>
internal void OnPropertyChanged(PropertyChangedEventArgs args)
=> PropertyChanged?.Invoke(this, args);

/// <summary>
/// Raises the <see cref="PropertyChanging"/> event.
/// </summary>
/// <param name="propertyName">The name of the property that is changing.</param>
protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
=> PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));

/// <summary>
/// Raises the <see cref="PropertyChanging"/> event using a cached PropertyChangingEventArgs.
/// </summary>
/// <param name="args">The cached PropertyChangingEventArgs to use.</param>
internal void OnPropertyChanging(PropertyChangingEventArgs args)
=> PropertyChanging?.Invoke(this, args);

/// <summary>
/// Removes all current bindings from the current context.
/// </summary>
Expand Down Expand Up @@ -639,7 +656,7 @@ void SetValueActual(BindableProperty property, BindablePropertyContext context,
{
property.PropertyChanging?.Invoke(this, original, value);

OnPropertyChanging(property.PropertyName);
OnPropertyChanging(property.GetPropertyChangingEventArgs());
}

context.Values[specificity] = value;
Expand Down Expand Up @@ -672,18 +689,16 @@ private protected virtual void OnBindablePropertySet(BindableProperty property,
{
if (willFirePropertyChanged)
{
OnPropertyChanged(property.PropertyName);
OnPropertyChanged(property.GetPropertyChangedEventArgs());
property.PropertyChanged?.Invoke(this, original, value);
}
}

void ApplyBindings(bool fromBindingContextChanged)
{
var prop = _properties.Values.ToArray();

for (int i = 0, propLength = prop.Length; i < propLength; i++)
foreach (var kvp in _properties)
{
BindablePropertyContext context = prop[i];
BindablePropertyContext context = kvp.Value;
if (ReferenceEquals(context.Property, BindingContextProperty))
{
// BindingContextProperty Binding is handled separately within SetInheritedBindingContext
Expand Down
9 changes: 9 additions & 0 deletions src/Controls/src/Core/BindableProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,15 @@ public sealed class BindableProperty

internal ValidateValueDelegate ValidateValue { get; private set; }

PropertyChangedEventArgs _cachedPropertyChangedEventArgs;
PropertyChangingEventArgs _cachedPropertyChangingEventArgs;

internal PropertyChangedEventArgs GetPropertyChangedEventArgs()
=> _cachedPropertyChangedEventArgs ??= new PropertyChangedEventArgs(PropertyName);

internal PropertyChangingEventArgs GetPropertyChangingEventArgs()
=> _cachedPropertyChangingEventArgs ??= new PropertyChangingEventArgs(PropertyName);

/// <summary>Creates a new instance of the BindableProperty class.</summary>
/// <param name="propertyName">The name of the BindableProperty.</param>
/// <param name="returnType">The type of the property.</param>
Expand Down
27 changes: 22 additions & 5 deletions src/Controls/src/Core/Element/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -668,14 +668,19 @@ protected virtual void OnParentSet()
}

HashSet<string> _pendingHandlerUpdatesFromBPSet = new HashSet<string>();
BindableProperty _currentPropertyBeingSet;

private protected override void OnBindablePropertySet(BindableProperty property, object original, object value, bool changed, bool willFirePropertyChanged)
{
if (willFirePropertyChanged)
{
_pendingHandlerUpdatesFromBPSet.Add(property.PropertyName);
}

_currentPropertyBeingSet = property;
base.OnBindablePropertySet(property, original, value, changed, willFirePropertyChanged);
_currentPropertyBeingSet = null;

_pendingHandlerUpdatesFromBPSet.Remove(property.PropertyName);
UpdateHandlerValue(property.PropertyName, changed);

Expand All @@ -702,7 +707,7 @@ protected override void OnPropertyChanged([CallerMemberName] string propertyName

if (_effects?.Count > 0)
{
var args = new PropertyChangedEventArgs(propertyName);
var args = _currentPropertyBeingSet?.GetPropertyChangedEventArgs() ?? new PropertyChangedEventArgs(propertyName);
foreach (Effect effect in _effects)
{
effect?.SendOnElementPropertyChanged(args);
Expand Down Expand Up @@ -946,14 +951,26 @@ internal INameScope GetNameScope()

void OnDescendantAdded(Element child)
{
DescendantAdded?.Invoke(this, new ElementEventArgs(child));
RealParent?.OnDescendantAdded(child);
var args = new ElementEventArgs(child);
OnDescendantAdded(args);
}

void OnDescendantAdded(ElementEventArgs args)
{
DescendantAdded?.Invoke(this, args);
RealParent?.OnDescendantAdded(args);
}

void OnDescendantRemoved(Element child)
{
DescendantRemoved?.Invoke(this, new ElementEventArgs(child));
RealParent?.OnDescendantRemoved(child);
var args = new ElementEventArgs(child);
OnDescendantRemoved(args);
}

void OnDescendantRemoved(ElementEventArgs args)
{
DescendantRemoved?.Invoke(this, args);
RealParent?.OnDescendantRemoved(args);
}

void OnResourceChanged(BindableProperty property, object value, SetterSpecificity specificity)
Expand Down
Loading