MultiBinding.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / Data / MultiBinding.cs / 2 / MultiBinding.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: Defines MultiBinding object, uses a collection of bindings together. 
// 
// Specs:       http://avalon/connecteddata/M5%20Specs/UIBinding.mht
// 
//---------------------------------------------------------------------------

using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Diagnostics;
using System.Globalization; 
using System.Windows.Controls;  // Validation
using System.Windows.Markup;
using MS.Internal.Controls; // Validation
using MS.Internal.Data; 
using MS.Utility;
 
namespace System.Windows.Data 
{
 
/// 
///  Describes a collection of bindings attached to a single property.
///     The inner bindings contribute their values to the MultiBinding,
///     which combines/converts them into a resultant final value. 
///     In the reverse direction, the target value is tranlated to
///     a set of values that are fed back into the inner bindings. 
///  
[ContentProperty("Bindings")]
public class MultiBinding : BindingBase, IAddChild 
{

    //-----------------------------------------------------
    // 
    //  Constructors
    // 
    //----------------------------------------------------- 

    ///  Default constructor  
    public MultiBinding()
    {
        _bindingCollection = new BindingCollection(this, new BindingCollectionChangedCallback(OnBindingCollectionChanged));
    } 

#region IAddChild 
 
    ///
    /// Called to Add the object as a Child. 
    ///
    ///
    /// Object to add as a child - must have type BindingBase
    /// 
    void IAddChild.AddChild(Object value)
    { 
        BindingBase binding = value as BindingBase; 
        if (binding != null)
            Bindings.Add(binding); 
        else
            throw new ArgumentException(SR.Get(SRID.ChildHasWrongType, this.GetType().Name, "BindingBase", value.GetType().FullName), "value");
    }
 
    ///
    /// Called when text appears under the tag in markup 
    /// 
    ///
    /// Text to Add to the Object 
    ///
    void IAddChild.AddText(string text)
    {
        XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this); 
    }
 
#endregion IAddChild 

    //------------------------------------------------------ 
    //
    //  Public Properties
    //
    //----------------------------------------------------- 

    ///  List of inner bindings  
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    public Collection Bindings
    { 
        get { return _bindingCollection; }
    }

    ///  
    /// This method is used by TypeDescriptor to determine if this property should
    /// be serialized. 
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)]
    public bool ShouldSerializeBindings() 
    {
        return (Bindings != null && Bindings.Count > 0);
    }
 
    ///  Binding type 
    [DefaultValue(BindingMode.Default)] 
    public BindingMode Mode 
    {
        get 
        {
            switch (GetFlagsWithinMask(BindingFlags.PropagationMask))
            {
                case BindingFlags.OneWay:           return BindingMode.OneWay; 
                case BindingFlags.TwoWay:           return BindingMode.TwoWay;
                case BindingFlags.OneWayToSource:   return BindingMode.OneWayToSource; 
                case BindingFlags.OneTime:          return BindingMode.OneTime; 
                case BindingFlags.PropDefault:      return BindingMode.Default;
            } 
            Debug.Assert(false, "Unexpected BindingMode value");
            return 0;
        }
        set 
        {
            CheckSealed(); 
            ChangeFlagsWithinMask(BindingFlags.PropagationMask, FlagsFrom(value)); 
        }
    } 

    ///  Update type 
    [DefaultValue(UpdateSourceTrigger.PropertyChanged)]
    public UpdateSourceTrigger UpdateSourceTrigger 
    {
        get 
        { 
            switch (GetFlagsWithinMask(BindingFlags.UpdateMask))
            { 
                case BindingFlags.UpdateOnPropertyChanged:    return UpdateSourceTrigger.PropertyChanged;
                case BindingFlags.UpdateOnLostFocus:    return UpdateSourceTrigger.LostFocus;
                case BindingFlags.UpdateExplicitly:     return UpdateSourceTrigger.Explicit;
                case BindingFlags.UpdateDefault:        return UpdateSourceTrigger.Default; 
            }
            Debug.Assert(false, "Unexpected UpdateSourceTrigger value"); 
            return 0; 
        }
        set 
        {
            CheckSealed();
            ChangeFlagsWithinMask(BindingFlags.UpdateMask, FlagsFrom(value));
        } 
    }
 
 
    ///  Raise SourceUpdated event whenever a value flows from target to source 
    [DefaultValue(false)] 
    public bool NotifyOnSourceUpdated
    {
        get
        { 
            return TestFlag(BindingFlags.NotifyOnSourceUpdated);
        } 
        set 
        {
            bool currentValue = TestFlag(BindingFlags.NotifyOnSourceUpdated); 
            if (currentValue != value)
            {
                CheckSealed();
                ChangeFlag(BindingFlags.NotifyOnSourceUpdated, value); 
            }
        } 
    } 

 
    ///  Raise TargetUpdated event whenever a value flows from source to target 
    [DefaultValue(false)]
    public bool NotifyOnTargetUpdated
    { 
        get
        { 
            return TestFlag(BindingFlags.NotifyOnTargetUpdated); 
        }
        set 
        {
            bool currentValue = TestFlag(BindingFlags.NotifyOnTargetUpdated);
            if (currentValue != value)
            { 
                CheckSealed();
                ChangeFlag(BindingFlags.NotifyOnTargetUpdated, value); 
            } 
        }
    } 

    ///  Raise ValidationError event whenever there is a ValidationError on Update
    [DefaultValue(false)]
    public bool NotifyOnValidationError 
    {
        get 
        { 
            return TestFlag(BindingFlags.NotifyOnValidationError);
        } 
        set
        {
            bool currentValue = TestFlag(BindingFlags.NotifyOnValidationError);
            if (currentValue != value) 
            {
                CheckSealed(); 
                ChangeFlag(BindingFlags.NotifyOnValidationError, value); 
            }
        } 
    }

    ///  Converter to convert the source values to/from the target value
    [DefaultValue(null)] 
    public IMultiValueConverter Converter
    { 
        get { return _converter; } 
        set { CheckSealed();  _converter = value; }
    } 

    /// 
    /// The parameter to pass to converter.
    ///  
    /// 
    [DefaultValue(null)] 
    public object ConverterParameter 
    {
        get { return _converterParameter; } 
        set { CheckSealed();  _converterParameter = value; }
    }

    ///  Culture in which to evaluate the converter  
    [DefaultValue(null)]
    [TypeConverter(typeof(System.Windows.CultureInfoIetfLanguageTagConverter))] 
    public CultureInfo ConverterCulture 
    {
        get { return _culture; } 
        set { CheckSealed();  _culture = value; }
    }

    ///  
    ///     Collection<ValidationRule> is a collection of ValidationRule
    ///     instances on either a Binding or a MultiBinding.  Each of the rules 
    ///     is checked for validity on update 
    /// 
    public Collection ValidationRules 
    {
        get
        {
            if (_validationRules == null) 
                _validationRules = new ValidationRuleCollection();
 
            return _validationRules; 
        }
 
    }

    /// 
    /// This method is used by TypeDescriptor to determine if this property should 
    /// be serialized.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public bool ShouldSerializeValidationRules()
    { 
        return (_validationRules != null && _validationRules.Count > 0);
    }

 
    /// 
    /// called whenever any exception is encountered when trying to update 
    /// the value to the source. The application author can provide its own 
    /// handler for handling exceptions here. If the delegate returns
    ///     null - don’t throw an error or provide a ValidationError. 
    ///     Exception - returns the exception itself, we will fire the exception using Async exception model.
    ///     ValidationError - it will set itself as the BindingInError and add it to the element’s Validation errors.
    /// 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public UpdateSourceExceptionFilterCallback UpdateSourceExceptionFilter
    { 
        get 
        {
            return _exceptionFilterCallback; 
        }

        set
        { 
            _exceptionFilterCallback = value;
        } 
    } 

    ///  True if an exception during source updates should be considered a validation error. 
    [DefaultValue(false)]
    public bool ValidatesOnExceptions
    {
        get 
        {
            return TestFlag(BindingFlags.ValidatesOnExceptions); 
        } 
        set
        { 
            bool currentValue = TestFlag(BindingFlags.ValidatesOnExceptions);
            if (currentValue != value)
            {
                CheckSealed(); 
                ChangeFlag(BindingFlags.ValidatesOnExceptions, value);
            } 
        } 
    }
 
    ///  True if a data error in the source item should be considered a validation error.
    [DefaultValue(false)]
    public bool ValidatesOnDataErrors
    { 
        get
        { 
            return TestFlag(BindingFlags.ValidatesOnDataErrors); 
        }
        set 
        {
            bool currentValue = TestFlag(BindingFlags.ValidatesOnDataErrors);
            if (currentValue != value)
            { 
                CheckSealed();
                ChangeFlag(BindingFlags.ValidatesOnDataErrors, value); 
            } 
        }
    } 

    //------------------------------------------------------
    //
    //  Protected Methods 
    //
    //------------------------------------------------------ 
 
    /// 
    /// Create an appropriate expression for this Binding, to be attached 
    /// to the given DependencyProperty on the given DependencyObject.
    /// 
    internal override BindingExpressionBase CreateBindingExpressionOverride(DependencyObject target, DependencyProperty dp, BindingExpressionBase owner)
    { 
        if (Converter == null && String.IsNullOrEmpty(StringFormat))
            throw new InvalidOperationException(SR.Get(SRID.MultiBindingHasNoConverter)); 
 
        for (int i = 0; i < Bindings.Count; ++i)
        { 
            CheckTrigger(Bindings[i]);
        }

        return MultiBindingExpression.CreateBindingExpression(target, dp, this, owner); 
    }
 
    internal override ValidationRule LookupValidationRule(Type type) 
    {
        return LookupValidationRule(type, ValidationRulesInternal); 
    }

    //-----------------------------------------------------
    // 
    //  Internal Methods
    // 
    //------------------------------------------------------ 

    internal object DoFilterException(object bindExpr, Exception exception) 
    {
        if (_exceptionFilterCallback != null)
            return _exceptionFilterCallback(bindExpr, exception);
 
        return exception;
    } 
 
    internal static void CheckTrigger(BindingBase bb)
    { 
        Binding binding = bb as Binding;
        if (binding != null)
        {
            if (binding.UpdateSourceTrigger != UpdateSourceTrigger.PropertyChanged && 
                binding.UpdateSourceTrigger != UpdateSourceTrigger.Default)
                throw new InvalidOperationException(SR.Get(SRID.NoUpdateSourceTriggerForInnerBindingOfMultiBinding)); 
        } 
    }
 
    //-----------------------------------------------------
    //
    //  Internal Properties
    // 
    //-----------------------------------------------------
 
    // same as the public ValidationRules property, but 
    // doesn't try to create an instance if there isn't one there
    internal override Collection ValidationRulesInternal 
    {
        get
        {
            return _validationRules; 
        }
    } 
 
    internal override CultureInfo ConverterCultureInternal
    { 
        get { return ConverterCulture; }
    }

    //----------------------------------------------------- 
    //
    //  Private Methods 
    // 
    //------------------------------------------------------
 
    private void OnBindingCollectionChanged()
    {
        CheckSealed();
    } 

    //----------------------------------------------------- 
    // 
    //  Private Fields
    // 
    //------------------------------------------------------

    BindingCollection       _bindingCollection;
    IMultiValueConverter    _converter; 
    object                  _converterParameter;
    CultureInfo             _culture; 
 
    ValidationRuleCollection _validationRules;
    UpdateSourceExceptionFilterCallback _exceptionFilterCallback; 
}

}

// 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 MultiBinding object, uses a collection of bindings together. 
// 
// Specs:       http://avalon/connecteddata/M5%20Specs/UIBinding.mht
// 
//---------------------------------------------------------------------------

using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Diagnostics;
using System.Globalization; 
using System.Windows.Controls;  // Validation
using System.Windows.Markup;
using MS.Internal.Controls; // Validation
using MS.Internal.Data; 
using MS.Utility;
 
namespace System.Windows.Data 
{
 
/// 
///  Describes a collection of bindings attached to a single property.
///     The inner bindings contribute their values to the MultiBinding,
///     which combines/converts them into a resultant final value. 
///     In the reverse direction, the target value is tranlated to
///     a set of values that are fed back into the inner bindings. 
///  
[ContentProperty("Bindings")]
public class MultiBinding : BindingBase, IAddChild 
{

    //-----------------------------------------------------
    // 
    //  Constructors
    // 
    //----------------------------------------------------- 

    ///  Default constructor  
    public MultiBinding()
    {
        _bindingCollection = new BindingCollection(this, new BindingCollectionChangedCallback(OnBindingCollectionChanged));
    } 

#region IAddChild 
 
    ///
    /// Called to Add the object as a Child. 
    ///
    ///
    /// Object to add as a child - must have type BindingBase
    /// 
    void IAddChild.AddChild(Object value)
    { 
        BindingBase binding = value as BindingBase; 
        if (binding != null)
            Bindings.Add(binding); 
        else
            throw new ArgumentException(SR.Get(SRID.ChildHasWrongType, this.GetType().Name, "BindingBase", value.GetType().FullName), "value");
    }
 
    ///
    /// Called when text appears under the tag in markup 
    /// 
    ///
    /// Text to Add to the Object 
    ///
    void IAddChild.AddText(string text)
    {
        XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this); 
    }
 
#endregion IAddChild 

    //------------------------------------------------------ 
    //
    //  Public Properties
    //
    //----------------------------------------------------- 

    ///  List of inner bindings  
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    public Collection Bindings
    { 
        get { return _bindingCollection; }
    }

    ///  
    /// This method is used by TypeDescriptor to determine if this property should
    /// be serialized. 
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)]
    public bool ShouldSerializeBindings() 
    {
        return (Bindings != null && Bindings.Count > 0);
    }
 
    ///  Binding type 
    [DefaultValue(BindingMode.Default)] 
    public BindingMode Mode 
    {
        get 
        {
            switch (GetFlagsWithinMask(BindingFlags.PropagationMask))
            {
                case BindingFlags.OneWay:           return BindingMode.OneWay; 
                case BindingFlags.TwoWay:           return BindingMode.TwoWay;
                case BindingFlags.OneWayToSource:   return BindingMode.OneWayToSource; 
                case BindingFlags.OneTime:          return BindingMode.OneTime; 
                case BindingFlags.PropDefault:      return BindingMode.Default;
            } 
            Debug.Assert(false, "Unexpected BindingMode value");
            return 0;
        }
        set 
        {
            CheckSealed(); 
            ChangeFlagsWithinMask(BindingFlags.PropagationMask, FlagsFrom(value)); 
        }
    } 

    ///  Update type 
    [DefaultValue(UpdateSourceTrigger.PropertyChanged)]
    public UpdateSourceTrigger UpdateSourceTrigger 
    {
        get 
        { 
            switch (GetFlagsWithinMask(BindingFlags.UpdateMask))
            { 
                case BindingFlags.UpdateOnPropertyChanged:    return UpdateSourceTrigger.PropertyChanged;
                case BindingFlags.UpdateOnLostFocus:    return UpdateSourceTrigger.LostFocus;
                case BindingFlags.UpdateExplicitly:     return UpdateSourceTrigger.Explicit;
                case BindingFlags.UpdateDefault:        return UpdateSourceTrigger.Default; 
            }
            Debug.Assert(false, "Unexpected UpdateSourceTrigger value"); 
            return 0; 
        }
        set 
        {
            CheckSealed();
            ChangeFlagsWithinMask(BindingFlags.UpdateMask, FlagsFrom(value));
        } 
    }
 
 
    ///  Raise SourceUpdated event whenever a value flows from target to source 
    [DefaultValue(false)] 
    public bool NotifyOnSourceUpdated
    {
        get
        { 
            return TestFlag(BindingFlags.NotifyOnSourceUpdated);
        } 
        set 
        {
            bool currentValue = TestFlag(BindingFlags.NotifyOnSourceUpdated); 
            if (currentValue != value)
            {
                CheckSealed();
                ChangeFlag(BindingFlags.NotifyOnSourceUpdated, value); 
            }
        } 
    } 

 
    ///  Raise TargetUpdated event whenever a value flows from source to target 
    [DefaultValue(false)]
    public bool NotifyOnTargetUpdated
    { 
        get
        { 
            return TestFlag(BindingFlags.NotifyOnTargetUpdated); 
        }
        set 
        {
            bool currentValue = TestFlag(BindingFlags.NotifyOnTargetUpdated);
            if (currentValue != value)
            { 
                CheckSealed();
                ChangeFlag(BindingFlags.NotifyOnTargetUpdated, value); 
            } 
        }
    } 

    ///  Raise ValidationError event whenever there is a ValidationError on Update
    [DefaultValue(false)]
    public bool NotifyOnValidationError 
    {
        get 
        { 
            return TestFlag(BindingFlags.NotifyOnValidationError);
        } 
        set
        {
            bool currentValue = TestFlag(BindingFlags.NotifyOnValidationError);
            if (currentValue != value) 
            {
                CheckSealed(); 
                ChangeFlag(BindingFlags.NotifyOnValidationError, value); 
            }
        } 
    }

    ///  Converter to convert the source values to/from the target value
    [DefaultValue(null)] 
    public IMultiValueConverter Converter
    { 
        get { return _converter; } 
        set { CheckSealed();  _converter = value; }
    } 

    /// 
    /// The parameter to pass to converter.
    ///  
    /// 
    [DefaultValue(null)] 
    public object ConverterParameter 
    {
        get { return _converterParameter; } 
        set { CheckSealed();  _converterParameter = value; }
    }

    ///  Culture in which to evaluate the converter  
    [DefaultValue(null)]
    [TypeConverter(typeof(System.Windows.CultureInfoIetfLanguageTagConverter))] 
    public CultureInfo ConverterCulture 
    {
        get { return _culture; } 
        set { CheckSealed();  _culture = value; }
    }

    ///  
    ///     Collection<ValidationRule> is a collection of ValidationRule
    ///     instances on either a Binding or a MultiBinding.  Each of the rules 
    ///     is checked for validity on update 
    /// 
    public Collection ValidationRules 
    {
        get
        {
            if (_validationRules == null) 
                _validationRules = new ValidationRuleCollection();
 
            return _validationRules; 
        }
 
    }

    /// 
    /// This method is used by TypeDescriptor to determine if this property should 
    /// be serialized.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public bool ShouldSerializeValidationRules()
    { 
        return (_validationRules != null && _validationRules.Count > 0);
    }

 
    /// 
    /// called whenever any exception is encountered when trying to update 
    /// the value to the source. The application author can provide its own 
    /// handler for handling exceptions here. If the delegate returns
    ///     null - don’t throw an error or provide a ValidationError. 
    ///     Exception - returns the exception itself, we will fire the exception using Async exception model.
    ///     ValidationError - it will set itself as the BindingInError and add it to the element’s Validation errors.
    /// 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public UpdateSourceExceptionFilterCallback UpdateSourceExceptionFilter
    { 
        get 
        {
            return _exceptionFilterCallback; 
        }

        set
        { 
            _exceptionFilterCallback = value;
        } 
    } 

    ///  True if an exception during source updates should be considered a validation error. 
    [DefaultValue(false)]
    public bool ValidatesOnExceptions
    {
        get 
        {
            return TestFlag(BindingFlags.ValidatesOnExceptions); 
        } 
        set
        { 
            bool currentValue = TestFlag(BindingFlags.ValidatesOnExceptions);
            if (currentValue != value)
            {
                CheckSealed(); 
                ChangeFlag(BindingFlags.ValidatesOnExceptions, value);
            } 
        } 
    }
 
    ///  True if a data error in the source item should be considered a validation error.
    [DefaultValue(false)]
    public bool ValidatesOnDataErrors
    { 
        get
        { 
            return TestFlag(BindingFlags.ValidatesOnDataErrors); 
        }
        set 
        {
            bool currentValue = TestFlag(BindingFlags.ValidatesOnDataErrors);
            if (currentValue != value)
            { 
                CheckSealed();
                ChangeFlag(BindingFlags.ValidatesOnDataErrors, value); 
            } 
        }
    } 

    //------------------------------------------------------
    //
    //  Protected Methods 
    //
    //------------------------------------------------------ 
 
    /// 
    /// Create an appropriate expression for this Binding, to be attached 
    /// to the given DependencyProperty on the given DependencyObject.
    /// 
    internal override BindingExpressionBase CreateBindingExpressionOverride(DependencyObject target, DependencyProperty dp, BindingExpressionBase owner)
    { 
        if (Converter == null && String.IsNullOrEmpty(StringFormat))
            throw new InvalidOperationException(SR.Get(SRID.MultiBindingHasNoConverter)); 
 
        for (int i = 0; i < Bindings.Count; ++i)
        { 
            CheckTrigger(Bindings[i]);
        }

        return MultiBindingExpression.CreateBindingExpression(target, dp, this, owner); 
    }
 
    internal override ValidationRule LookupValidationRule(Type type) 
    {
        return LookupValidationRule(type, ValidationRulesInternal); 
    }

    //-----------------------------------------------------
    // 
    //  Internal Methods
    // 
    //------------------------------------------------------ 

    internal object DoFilterException(object bindExpr, Exception exception) 
    {
        if (_exceptionFilterCallback != null)
            return _exceptionFilterCallback(bindExpr, exception);
 
        return exception;
    } 
 
    internal static void CheckTrigger(BindingBase bb)
    { 
        Binding binding = bb as Binding;
        if (binding != null)
        {
            if (binding.UpdateSourceTrigger != UpdateSourceTrigger.PropertyChanged && 
                binding.UpdateSourceTrigger != UpdateSourceTrigger.Default)
                throw new InvalidOperationException(SR.Get(SRID.NoUpdateSourceTriggerForInnerBindingOfMultiBinding)); 
        } 
    }
 
    //-----------------------------------------------------
    //
    //  Internal Properties
    // 
    //-----------------------------------------------------
 
    // same as the public ValidationRules property, but 
    // doesn't try to create an instance if there isn't one there
    internal override Collection ValidationRulesInternal 
    {
        get
        {
            return _validationRules; 
        }
    } 
 
    internal override CultureInfo ConverterCultureInternal
    { 
        get { return ConverterCulture; }
    }

    //----------------------------------------------------- 
    //
    //  Private Methods 
    // 
    //------------------------------------------------------
 
    private void OnBindingCollectionChanged()
    {
        CheckSealed();
    } 

    //----------------------------------------------------- 
    // 
    //  Private Fields
    // 
    //------------------------------------------------------

    BindingCollection       _bindingCollection;
    IMultiValueConverter    _converter; 
    object                  _converterParameter;
    CultureInfo             _culture; 
 
    ValidationRuleCollection _validationRules;
    UpdateSourceExceptionFilterCallback _exceptionFilterCallback; 
}

}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK