Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Data / PriorityBindingExpression.cs / 1 / PriorityBindingExpression.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description: Defines PriorityBindingExpression object, which chooses a BindingExpression out
// of a list of BindingExpressions in order of "priority" (and falls back
// to the next BindingExpression as each BindingExpression fails)
//
// See spec at http://avalon/connecteddata/Specs/Data%20Binding.mht
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.ObjectModel; // Collection
using System.Diagnostics;
using System.Threading;
using System.Windows.Controls; // ValidationStep
using System.Windows.Threading;
using System.Windows.Markup;
using MS.Internal;
using MS.Internal.Data;
using MS.Utility;
namespace System.Windows.Data
{
///
/// Describes a collection of BindingExpressions attached to a single property.
/// These behave as "priority" BindingExpressions, meaning that the property
/// receives its value from the first BindingExpression in the collection that
/// can produce a legal value.
///
public sealed class PriorityBindingExpression : BindingExpressionBase
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
private PriorityBindingExpression(PriorityBinding binding, BindingExpressionBase owner)
: base(binding, owner)
{
}
//------------------------------------------------------
//
// Public Properties
//
//-----------------------------------------------------
/// Binding from which this expression was created
public PriorityBinding ParentPriorityBinding { get { return (PriorityBinding)ParentBindingBase; } }
/// List of inner BindingExpression
public ReadOnlyCollection BindingExpressions
{
get { return new ReadOnlyCollection(MutableBindingExpressions); }
}
/// Returns the active BindingExpression (or null)
public BindingExpressionBase ActiveBindingExpression
{
get { return (_activeIndex < 0) ? null : MutableBindingExpressions[_activeIndex]; }
}
//------------------------------------------------------
//
// Public Methods
//
//------------------------------------------------------
#region Expression overrides
///
/// Called to evaluate the Expression value
///
/// DependencyObject being queried
/// Property being queried
/// Computed value. Unset if unavailable.
internal override object GetValue(DependencyObject d, DependencyProperty dp)
{
return Value;
}
///
/// Allows Expression to store set values
///
/// DependencyObject being set
/// Property being set
/// Value being set
/// true if Expression handled storing of the value
internal override bool SetValue(DependencyObject d, DependencyProperty dp, object value)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
return bindExpr.SetValue(d, dp, value);
// If we couldn't find the active binding, just return true to keep the property
// engine from removing the PriorityBinding.
return true;
}
///
/// Notification that a Dependent that this Expression established has
/// been invalidated as a result of a Source invalidation
///
/// DependencyObject that was invalidated
/// Changed event args for the property that was invalidated
internal override void OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
// If this method is changed to use d or dp directly, uncomment these lines
//if (d == null)
// throw new ArgumentNullException(d);
//if (dp == null)
// throw new ArgumentNullException(dp);
// if the notification arrived on the right Dispatcher, handle it now.
if (Dispatcher.Thread == Thread.CurrentThread)
{
HandlePropertyInvalidation(d, args);
}
else // Otherwise, marshal it to the right Dispatcher.
{
Dispatcher.BeginInvoke(
DispatcherPriority.DataBind,
new DispatcherOperationCallback(HandlePropertyInvalidationOperation),
new object[]{d, args});
}
}
#endregion Expression overrides
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
// Create a new BindingExpression from the given Binding description
internal static PriorityBindingExpression CreateBindingExpression(DependencyObject d, DependencyProperty dp, PriorityBinding binding, BindingExpressionBase owner)
{
FrameworkPropertyMetadata fwMetaData = dp.GetMetadata(d.DependencyObjectType) as FrameworkPropertyMetadata;
if ((fwMetaData != null && !fwMetaData.IsDataBindingAllowed) || dp.ReadOnly)
throw new ArgumentException(SR.Get(SRID.PropertyNotBindable, dp.Name), "dp");
// create the BindingExpression
PriorityBindingExpression bindExpr = new PriorityBindingExpression(binding, owner);
return bindExpr;
}
//-----------------------------------------------------
//
// Protected Internal Properties
//
//-----------------------------------------------------
///
/// Number of BindingExpressions that have been attached and are listening
///
internal int AttentiveBindingExpressions
{
get { return (_activeIndex == NoActiveBindingExpressions) ? MutableBindingExpressions.Count : _activeIndex + 1; }
}
//-----------------------------------------------------
//
// Protected Internal Methods
//
//------------------------------------------------------
///
/// Attach a BindingExpression to the given target (element, property)
///
/// DependencyObject being set
/// Property being set
internal override void AttachOverride(DependencyObject d, DependencyProperty dp)
{
base.AttachOverride(d, dp);
DependencyObject target = TargetElement;
if (target == null)
return;
SetStatus(BindingStatus.Active);
int count = ParentPriorityBinding.Bindings.Count;
_activeIndex = NoActiveBindingExpressions;
Debug.Assert(MutableBindingExpressions.Count == 0, "expect to encounter empty BindingExpression collection when attaching MultiBinding");
for (int i = 0; i < count; ++i)
{
AttachBindingExpression(i, false); // create new binding and have it added to end
}
}
/// sever all connections
internal override void DetachOverride()
{
// Theoretically, we only need to detach number of AttentiveBindings,
// but we'll traverse the whole list anyway and do aggressive clean-up.
int count = MutableBindingExpressions.Count;
for (int i = 0; i < count; ++i)
{
BindingExpressionBase b = MutableBindingExpressions[i];
if (b != null)
b.Detach();
}
ChangeSources(null);
base.DetachOverride();
}
///
/// Invalidate the given child expression.
///
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.Status != BindingStatus.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.Trace(TraceEventType.Warning,
TraceData.PriorityTransfer(
TraceData.Identify(this),
TraceData.Identify(newValue),
_activeIndex,
TraceData.Identify(bindExpr)));
}
// 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;
}
///
/// Change the dependency sources for the given child expression.
///
internal override void ChangeSourcesForChild(BindingExpressionBase bindingExpression, WeakDependencySource[] newSources)
{
int index = MutableBindingExpressions.IndexOf(bindingExpression);
if (index >= 0)
{
WeakDependencySource[] combinedSources = CombineSources(index, MutableBindingExpressions, AttentiveBindingExpressions, newSources);
ChangeSources(combinedSources);
}
}
///
/// Replace the given child expression with a new one.
///
internal override void ReplaceChild(BindingExpressionBase bindingExpression)
{
int index = MutableBindingExpressions.IndexOf(bindingExpression);
DependencyObject target = TargetElement;
if (index >= 0 && target != null)
{
// clean up the old BindingExpression
bindingExpression.Detach();
// create a replacement BindingExpression and put it in the collection
bindingExpression = AttachBindingExpression(index, true);
}
}
// register the leaf bindings with the binding group
internal override void UpdateBindingGroup(BindingGroup bg)
{
for (int i=0, n=MutableBindingExpressions.Count-1; i
/// Get the raw proposed value
///
internal override object GetRawProposedValue()
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.GetRawProposedValue();
}
return DependencyProperty.UnsetValue;
}
///
/// Get the converted proposed value
///
internal override object ConvertProposedValue(object rawValue)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.ConvertProposedValue(rawValue);
}
return DependencyProperty.UnsetValue;
}
///
/// Get the converted proposed value and inform the binding group
///
internal override void ObtainConvertedProposedValue(BindingGroup bindingGroup)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
bindExpr.ObtainConvertedProposedValue(bindingGroup);
}
}
///
/// Update the source value and inform the binding group
///
internal override object UpdateSource(object convertedValue)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.UpdateSource(convertedValue);
}
return DependencyProperty.UnsetValue;
}
///
/// Update the source value and inform the binding group
///
internal override void UpdateSource(BindingGroup bindingGroup)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
bindExpr.UpdateSource(bindingGroup);
}
}
///
/// Store the value in the binding group
///
internal override void StoreValueInBindingGroup(object value, BindingGroup bindingGroup)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
bindExpr.StoreValueInBindingGroup(value, bindingGroup);
}
}
///
/// Run validation rules for the given step
///
internal override bool Validate(object value, ValidationStep validationStep)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.Validate(value, validationStep);
}
return true;
}
///
/// Run validation rules for the given step, and inform the binding group
///
internal override bool CheckValidationRules(BindingGroup bindingGroup, ValidationStep validationStep)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.CheckValidationRules(bindingGroup, validationStep);
}
return true;
}
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
///
/// expose a mutable version of the list of all BindingExpressions;
/// derived internal classes need to be able to populate this list
///
private Collection MutableBindingExpressions
{
get { return _list; }
}
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
// Create a BindingExpression for position i
BindingExpressionBase AttachBindingExpression(int i, bool replaceExisting)
{
DependencyObject target = TargetElement;
if (target == null)
return null;
BindingBase binding = ParentPriorityBinding.Bindings[i];
BindingExpressionBase bindExpr = binding.CreateBindingExpression(target, TargetProperty, this);
if (replaceExisting) // replace exisiting or add as new binding?
MutableBindingExpressions[i] = bindExpr;
else
MutableBindingExpressions.Add(bindExpr);
bindExpr.Attach(target, TargetProperty);
return bindExpr;
}
// Re-evaluate the choice of active BindingExpression
void ChooseActiveBindingExpression(DependencyObject target)
{
int i, count = MutableBindingExpressions.Count;
for (i = 0; i < count; ++i)
{
BindingExpressionBase bindExpr = MutableBindingExpressions[i];
// Try to activate the BindingExpression if it isn't already activate
if (bindExpr.Status == BindingStatus.Inactive)
bindExpr.Activate();
if (bindExpr.Status == BindingStatus.Active || bindExpr.UsingFallbackValue)
break;
}
int newActiveIndex = (i < count) ? i : NoActiveBindingExpressions;
// if active changes, tell the property engine the new list of sources
if (newActiveIndex != _activeIndex)
{
int oldActiveIndex = _activeIndex;
// get new list of sources
_activeIndex = newActiveIndex;
WeakDependencySource[] newSources = CombineSources(-1, MutableBindingExpressions, AttentiveBindingExpressions, null);
// tell property engine
ChangeSources(newSources);
// deactivate BindingExpressions that don't need to be attentive
//
if (newActiveIndex != NoActiveBindingExpressions)
for (i = oldActiveIndex; i > newActiveIndex; --i)
MutableBindingExpressions[i].Deactivate();
}
}
private void ChangeValue()
{
}
private object HandlePropertyInvalidationOperation(object o)
{
// This is the case where the source of the Binding belonged to a different Dispatcher
// than the target. For this scenario the source marshals off the invalidation information
// onto the target's Dispatcher queue. This is where we unpack the marshalled information
// to fire the invalidation on the target object.
object[] args = (object[])o;
HandlePropertyInvalidation((DependencyObject)args[0], (DependencyPropertyChangedEventArgs)args[1]);
return null;
}
private void HandlePropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
DependencyProperty dp = args.Property;
int n = AttentiveBindingExpressions;
if (TraceData.IsExtendedTraceEnabled(this, TraceDataLevel.Events))
{
TraceData.Trace(TraceEventType.Warning,
TraceData.GotPropertyChanged(
TraceData.Identify(this),
TraceData.Identify(d),
dp.Name));
}
for (int i=0; i _list = new Collection();
int _activeIndex = UnknownActiveBindingExpression;
bool _isInInvalidateBinding = false;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description: Defines PriorityBindingExpression object, which chooses a BindingExpression out
// of a list of BindingExpressions in order of "priority" (and falls back
// to the next BindingExpression as each BindingExpression fails)
//
// See spec at http://avalon/connecteddata/Specs/Data%20Binding.mht
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.ObjectModel; // Collection
using System.Diagnostics;
using System.Threading;
using System.Windows.Controls; // ValidationStep
using System.Windows.Threading;
using System.Windows.Markup;
using MS.Internal;
using MS.Internal.Data;
using MS.Utility;
namespace System.Windows.Data
{
///
/// Describes a collection of BindingExpressions attached to a single property.
/// These behave as "priority" BindingExpressions, meaning that the property
/// receives its value from the first BindingExpression in the collection that
/// can produce a legal value.
///
public sealed class PriorityBindingExpression : BindingExpressionBase
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
private PriorityBindingExpression(PriorityBinding binding, BindingExpressionBase owner)
: base(binding, owner)
{
}
//------------------------------------------------------
//
// Public Properties
//
//-----------------------------------------------------
/// Binding from which this expression was created
public PriorityBinding ParentPriorityBinding { get { return (PriorityBinding)ParentBindingBase; } }
/// List of inner BindingExpression
public ReadOnlyCollection BindingExpressions
{
get { return new ReadOnlyCollection(MutableBindingExpressions); }
}
/// Returns the active BindingExpression (or null)
public BindingExpressionBase ActiveBindingExpression
{
get { return (_activeIndex < 0) ? null : MutableBindingExpressions[_activeIndex]; }
}
//------------------------------------------------------
//
// Public Methods
//
//------------------------------------------------------
#region Expression overrides
///
/// Called to evaluate the Expression value
///
/// DependencyObject being queried
/// Property being queried
/// Computed value. Unset if unavailable.
internal override object GetValue(DependencyObject d, DependencyProperty dp)
{
return Value;
}
///
/// Allows Expression to store set values
///
/// DependencyObject being set
/// Property being set
/// Value being set
/// true if Expression handled storing of the value
internal override bool SetValue(DependencyObject d, DependencyProperty dp, object value)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
return bindExpr.SetValue(d, dp, value);
// If we couldn't find the active binding, just return true to keep the property
// engine from removing the PriorityBinding.
return true;
}
///
/// Notification that a Dependent that this Expression established has
/// been invalidated as a result of a Source invalidation
///
/// DependencyObject that was invalidated
/// Changed event args for the property that was invalidated
internal override void OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
// If this method is changed to use d or dp directly, uncomment these lines
//if (d == null)
// throw new ArgumentNullException(d);
//if (dp == null)
// throw new ArgumentNullException(dp);
// if the notification arrived on the right Dispatcher, handle it now.
if (Dispatcher.Thread == Thread.CurrentThread)
{
HandlePropertyInvalidation(d, args);
}
else // Otherwise, marshal it to the right Dispatcher.
{
Dispatcher.BeginInvoke(
DispatcherPriority.DataBind,
new DispatcherOperationCallback(HandlePropertyInvalidationOperation),
new object[]{d, args});
}
}
#endregion Expression overrides
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
// Create a new BindingExpression from the given Binding description
internal static PriorityBindingExpression CreateBindingExpression(DependencyObject d, DependencyProperty dp, PriorityBinding binding, BindingExpressionBase owner)
{
FrameworkPropertyMetadata fwMetaData = dp.GetMetadata(d.DependencyObjectType) as FrameworkPropertyMetadata;
if ((fwMetaData != null && !fwMetaData.IsDataBindingAllowed) || dp.ReadOnly)
throw new ArgumentException(SR.Get(SRID.PropertyNotBindable, dp.Name), "dp");
// create the BindingExpression
PriorityBindingExpression bindExpr = new PriorityBindingExpression(binding, owner);
return bindExpr;
}
//-----------------------------------------------------
//
// Protected Internal Properties
//
//-----------------------------------------------------
///
/// Number of BindingExpressions that have been attached and are listening
///
internal int AttentiveBindingExpressions
{
get { return (_activeIndex == NoActiveBindingExpressions) ? MutableBindingExpressions.Count : _activeIndex + 1; }
}
//-----------------------------------------------------
//
// Protected Internal Methods
//
//------------------------------------------------------
///
/// Attach a BindingExpression to the given target (element, property)
///
/// DependencyObject being set
/// Property being set
internal override void AttachOverride(DependencyObject d, DependencyProperty dp)
{
base.AttachOverride(d, dp);
DependencyObject target = TargetElement;
if (target == null)
return;
SetStatus(BindingStatus.Active);
int count = ParentPriorityBinding.Bindings.Count;
_activeIndex = NoActiveBindingExpressions;
Debug.Assert(MutableBindingExpressions.Count == 0, "expect to encounter empty BindingExpression collection when attaching MultiBinding");
for (int i = 0; i < count; ++i)
{
AttachBindingExpression(i, false); // create new binding and have it added to end
}
}
/// sever all connections
internal override void DetachOverride()
{
// Theoretically, we only need to detach number of AttentiveBindings,
// but we'll traverse the whole list anyway and do aggressive clean-up.
int count = MutableBindingExpressions.Count;
for (int i = 0; i < count; ++i)
{
BindingExpressionBase b = MutableBindingExpressions[i];
if (b != null)
b.Detach();
}
ChangeSources(null);
base.DetachOverride();
}
///
/// Invalidate the given child expression.
///
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.Status != BindingStatus.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.Trace(TraceEventType.Warning,
TraceData.PriorityTransfer(
TraceData.Identify(this),
TraceData.Identify(newValue),
_activeIndex,
TraceData.Identify(bindExpr)));
}
// 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;
}
///
/// Change the dependency sources for the given child expression.
///
internal override void ChangeSourcesForChild(BindingExpressionBase bindingExpression, WeakDependencySource[] newSources)
{
int index = MutableBindingExpressions.IndexOf(bindingExpression);
if (index >= 0)
{
WeakDependencySource[] combinedSources = CombineSources(index, MutableBindingExpressions, AttentiveBindingExpressions, newSources);
ChangeSources(combinedSources);
}
}
///
/// Replace the given child expression with a new one.
///
internal override void ReplaceChild(BindingExpressionBase bindingExpression)
{
int index = MutableBindingExpressions.IndexOf(bindingExpression);
DependencyObject target = TargetElement;
if (index >= 0 && target != null)
{
// clean up the old BindingExpression
bindingExpression.Detach();
// create a replacement BindingExpression and put it in the collection
bindingExpression = AttachBindingExpression(index, true);
}
}
// register the leaf bindings with the binding group
internal override void UpdateBindingGroup(BindingGroup bg)
{
for (int i=0, n=MutableBindingExpressions.Count-1; i
/// Get the raw proposed value
///
internal override object GetRawProposedValue()
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.GetRawProposedValue();
}
return DependencyProperty.UnsetValue;
}
///
/// Get the converted proposed value
///
internal override object ConvertProposedValue(object rawValue)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.ConvertProposedValue(rawValue);
}
return DependencyProperty.UnsetValue;
}
///
/// Get the converted proposed value and inform the binding group
///
internal override void ObtainConvertedProposedValue(BindingGroup bindingGroup)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
bindExpr.ObtainConvertedProposedValue(bindingGroup);
}
}
///
/// Update the source value and inform the binding group
///
internal override object UpdateSource(object convertedValue)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.UpdateSource(convertedValue);
}
return DependencyProperty.UnsetValue;
}
///
/// Update the source value and inform the binding group
///
internal override void UpdateSource(BindingGroup bindingGroup)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
bindExpr.UpdateSource(bindingGroup);
}
}
///
/// Store the value in the binding group
///
internal override void StoreValueInBindingGroup(object value, BindingGroup bindingGroup)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
bindExpr.StoreValueInBindingGroup(value, bindingGroup);
}
}
///
/// Run validation rules for the given step
///
internal override bool Validate(object value, ValidationStep validationStep)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.Validate(value, validationStep);
}
return true;
}
///
/// Run validation rules for the given step, and inform the binding group
///
internal override bool CheckValidationRules(BindingGroup bindingGroup, ValidationStep validationStep)
{
BindingExpressionBase bindExpr = ActiveBindingExpression;
if (bindExpr != null)
{
return bindExpr.CheckValidationRules(bindingGroup, validationStep);
}
return true;
}
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
///
/// expose a mutable version of the list of all BindingExpressions;
/// derived internal classes need to be able to populate this list
///
private Collection MutableBindingExpressions
{
get { return _list; }
}
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
// Create a BindingExpression for position i
BindingExpressionBase AttachBindingExpression(int i, bool replaceExisting)
{
DependencyObject target = TargetElement;
if (target == null)
return null;
BindingBase binding = ParentPriorityBinding.Bindings[i];
BindingExpressionBase bindExpr = binding.CreateBindingExpression(target, TargetProperty, this);
if (replaceExisting) // replace exisiting or add as new binding?
MutableBindingExpressions[i] = bindExpr;
else
MutableBindingExpressions.Add(bindExpr);
bindExpr.Attach(target, TargetProperty);
return bindExpr;
}
// Re-evaluate the choice of active BindingExpression
void ChooseActiveBindingExpression(DependencyObject target)
{
int i, count = MutableBindingExpressions.Count;
for (i = 0; i < count; ++i)
{
BindingExpressionBase bindExpr = MutableBindingExpressions[i];
// Try to activate the BindingExpression if it isn't already activate
if (bindExpr.Status == BindingStatus.Inactive)
bindExpr.Activate();
if (bindExpr.Status == BindingStatus.Active || bindExpr.UsingFallbackValue)
break;
}
int newActiveIndex = (i < count) ? i : NoActiveBindingExpressions;
// if active changes, tell the property engine the new list of sources
if (newActiveIndex != _activeIndex)
{
int oldActiveIndex = _activeIndex;
// get new list of sources
_activeIndex = newActiveIndex;
WeakDependencySource[] newSources = CombineSources(-1, MutableBindingExpressions, AttentiveBindingExpressions, null);
// tell property engine
ChangeSources(newSources);
// deactivate BindingExpressions that don't need to be attentive
//
if (newActiveIndex != NoActiveBindingExpressions)
for (i = oldActiveIndex; i > newActiveIndex; --i)
MutableBindingExpressions[i].Deactivate();
}
}
private void ChangeValue()
{
}
private object HandlePropertyInvalidationOperation(object o)
{
// This is the case where the source of the Binding belonged to a different Dispatcher
// than the target. For this scenario the source marshals off the invalidation information
// onto the target's Dispatcher queue. This is where we unpack the marshalled information
// to fire the invalidation on the target object.
object[] args = (object[])o;
HandlePropertyInvalidation((DependencyObject)args[0], (DependencyPropertyChangedEventArgs)args[1]);
return null;
}
private void HandlePropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
DependencyProperty dp = args.Property;
int n = AttentiveBindingExpressions;
if (TraceData.IsExtendedTraceEnabled(this, TraceDataLevel.Events))
{
TraceData.Trace(TraceEventType.Warning,
TraceData.GotPropertyChanged(
TraceData.Identify(this),
TraceData.Identify(d),
dp.Name));
}
for (int i=0; i _list = new Collection();
int _activeIndex = UnknownActiveBindingExpression;
bool _isInInvalidateBinding = false;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ListControlActionList.cs
- IDQuery.cs
- LinkClickEvent.cs
- GregorianCalendar.cs
- OutputScope.cs
- TransformerConfigurationWizardBase.cs
- SqlMethodTransformer.cs
- HttpHeaderCollection.cs
- AtomicFile.cs
- RepeatButton.cs
- QueueSurrogate.cs
- EntityDataSourceContainerNameItem.cs
- CodeParameterDeclarationExpression.cs
- Attachment.cs
- CryptoSession.cs
- GestureRecognitionResult.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- NameNode.cs
- DataGridViewTextBoxColumn.cs
- WizardForm.cs
- SecondaryIndex.cs
- MachineKeySection.cs
- CssStyleCollection.cs
- XsltLibrary.cs
- OdbcError.cs
- UnknownBitmapDecoder.cs
- ConnectionInterfaceCollection.cs
- AutomationPeer.cs
- SqlResolver.cs
- SamlAssertionDirectKeyIdentifierClause.cs
- StringUtil.cs
- BuildTopDownAttribute.cs
- DefaultProxySection.cs
- GridSplitterAutomationPeer.cs
- Accessors.cs
- Frame.cs
- PropertyDescriptorComparer.cs
- DiscoveryClientChannelBase.cs
- X509Extension.cs
- Ray3DHitTestResult.cs
- DbConnectionPoolGroupProviderInfo.cs
- CollectionViewProxy.cs
- SizeChangedEventArgs.cs
- DataGridViewCheckBoxCell.cs
- ModelPropertyDescriptor.cs
- BinHexEncoder.cs
- ParallelTimeline.cs
- CodeEventReferenceExpression.cs
- SqlDataSourceFilteringEventArgs.cs
- MarkupCompilePass2.cs
- SystemTcpConnection.cs
- IFlowDocumentViewer.cs
- MachineKeyConverter.cs
- IndependentAnimationStorage.cs
- Timer.cs
- WebPartEditVerb.cs
- Configuration.cs
- IncrementalHitTester.cs
- CharacterMetrics.cs
- DataSourceExpressionCollection.cs
- Clipboard.cs
- SetStateEventArgs.cs
- StrokeSerializer.cs
- IdentityValidationException.cs
- DesignerActionPanel.cs
- MenuItemCollection.cs
- ScriptResourceMapping.cs
- DataServiceQueryOfT.cs
- NameObjectCollectionBase.cs
- SelectionItemPattern.cs
- Grid.cs
- MaskedTextProvider.cs
- DynamicObjectAccessor.cs
- SignatureToken.cs
- SoapMessage.cs
- SimpleTypeResolver.cs
- BoundPropertyEntry.cs
- ReadOnlyDictionary.cs
- DataService.cs
- QueryCacheManager.cs
- FacetDescriptionElement.cs
- FontSizeConverter.cs
- DomainUpDown.cs
- SuspendDesigner.cs
- ArithmeticException.cs
- DBSqlParserColumnCollection.cs
- State.cs
- COM2PropertyDescriptor.cs
- SQLDouble.cs
- xmlglyphRunInfo.cs
- DataGridViewRowCancelEventArgs.cs
- SchemaConstraints.cs
- Pool.cs
- ObjectConverter.cs
- X509UI.cs
- QuadraticBezierSegment.cs
- ComPlusThreadInitializer.cs
- RtfToXamlLexer.cs
- WindowsFormsHelpers.cs
- ImageAnimator.cs