/// <summary>
/// Invalidate the given child expression.
/// </summary>
internal override void InvalidateChild(BindingExpressionBase bindingExpression)
{
// Prevent re-entrancy, because ChooseActiveBindingExpression() may
// activate/deactivate a BindingExpression that indirectly calls this again.
if (_isInInvalidateBinding)
{
return;
}
_isInInvalidateBinding = true;
int index = MutableBindingExpressions.IndexOf(bindingExpression);
DependencyObject target = TargetElement;
if (target != null && 0 <= index && index < AttentiveBindingExpressions)
{
// Optimization: only look for new ActiveBindingExpression when necessary:
// 1. it is a higher priority BindingExpression (or there's no ActiveBindingExpression), or
// 2. the existing ActiveBindingExpression is broken
if (index != _activeIndex ||
(bindingExpression.StatusInternal != BindingStatusInternal.Active && !bindingExpression.UsingFallbackValue))
{
ChooseActiveBindingExpression(target);
}
// update the value
UsingFallbackValue = false;
BindingExpressionBase bindExpr = ActiveBindingExpression;
object newValue = (bindExpr != null) ? bindExpr.GetValue(target, TargetProperty) : UseFallbackValue();
ChangeValue(newValue, true);
if (TraceData.IsExtendedTraceEnabled(this, TraceDataLevel.Transfer))
{
TraceData.TraceAndNotifyWithNoParameters(TraceEventType.Warning,
TraceData.PriorityTransfer(
TraceData.Identify(this),
TraceData.Identify(newValue),
_activeIndex,
TraceData.Identify(bindExpr)),
this);
}
// don't invalidate during Attach. The property engine does it
// already, and it would interfere with the on-demand activation
// of style-defined BindingExpressions.
if (!IsAttaching)
{
// recompute expression
target.InvalidateProperty(TargetProperty);
}
}
_isInInvalidateBinding = false;
}