RelativeSource.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Data / RelativeSource.cs / 1305600 / RelativeSource.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: Defines RelativeSource MarkupExtension. 
// 
//---------------------------------------------------------------------------
 
using System.ComponentModel;    // ISupportInitialize
using System.Diagnostics;
using System.Windows.Markup;    // MarkupExtension
 
namespace System.Windows.Data
{ 
 
    ///  This enum describes the type of RelativeSource
    ///  
    public enum RelativeSourceMode
    {
        /// use the DataContext from the previous scope
        ///  
        PreviousData,
 
        /// use the target element's styled parent 
        /// 
        TemplatedParent, 

        /// use the target element itself
        /// 
        Self, 

        /// use the target element's ancestor of a specified Type 
        ///  
        FindAncestor
    } 

    /// 
    ///
    /// RelativeSource Modes are 
    ///     PreviousData   - use the DataContext from the previous scope
    ///     TemplatedParent- use the target element's styled parent 
    ///     Self           - use the target element itself 
    ///     FindAncestor   - use the hosting Type
    /// Only FindAncestor mode allows AncestorType and AncestorLevel. 
    /// 
    [MarkupExtensionReturnType(typeof(RelativeSource))]
    public class RelativeSource : MarkupExtension, ISupportInitialize
    { 

#region constructors 
 
        /// Constructor
        ///  
        public RelativeSource()
        {
            // default mode to FindAncestor so that setting Type and Level would be OK
            _mode = RelativeSourceMode.FindAncestor; 
        }
 
        /// Constructor 
        /// 
        public RelativeSource(RelativeSourceMode mode) 
        {
            InitializeMode(mode);
        }
 
        /// Constructor for FindAncestor mode
        ///  
        public RelativeSource(RelativeSourceMode mode, Type ancestorType, int ancestorLevel) 
        {
            InitializeMode(mode); 
            AncestorType = ancestorType;
            AncestorLevel = ancestorLevel;
        }
 
#endregion constructors
 
#region ISupportInitialize 

        /// Begin Initialization 
        void ISupportInitialize.BeginInit()
        {
        }
 
        /// End Initialization, verify that internal state is consistent
        void ISupportInitialize.EndInit() 
        { 
            if (IsUninitialized)
                throw new InvalidOperationException(SR.Get(SRID.RelativeSourceNeedsMode)); 
            if (_mode == RelativeSourceMode.FindAncestor && (AncestorType == null))
                throw new InvalidOperationException(SR.Get(SRID.RelativeSourceNeedsAncestorType));
        }
 
#endregion ISupportInitialize
 
#region public properties 

        /// static instance of RelativeSource for PreviousData mode. 
        /// 
        public static RelativeSource PreviousData
        {
            get 
            {
                if (s_previousData == null) 
                { 
                    s_previousData = new RelativeSource(RelativeSourceMode.PreviousData);
                } 
                return s_previousData;
            }
        }
 
        /// static instance of RelativeSource for TemplatedParent mode.
        ///  
        public static RelativeSource TemplatedParent 
        {
            get 
            {
                if (s_templatedParent == null)
                {
                    s_templatedParent = new RelativeSource(RelativeSourceMode.TemplatedParent); 
                }
                return s_templatedParent; 
            } 
        }
 
        /// static instance of RelativeSource for Self mode.
        /// 
        public static RelativeSource Self
        { 
            get
            { 
                if (s_self == null) 
                {
                    s_self = new RelativeSource(RelativeSourceMode.Self); 
                }
                return s_self;
            }
        } 

        /// mode of RelativeSource 
        ///  
        ///  Mode is read-only after initialization.
        /// If Mode is not set explicitly, setting AncestorType or AncestorLevel will implicitly lock the Mode to FindAncestor.  
        ///  RelativeSource Mode is immutable after initialization;
        /// instead of changing the Mode on this instance, create a new RelativeSource or use a different static instance. 
        [ConstructorArgument("mode")]
        public RelativeSourceMode Mode 
        {
            get { return _mode; } 
            set 
            {
                if (IsUninitialized) 
                {
                    InitializeMode(value);
                }
                else if (value != _mode)    // mode changes are not allowed 
                {
                    throw new InvalidOperationException(SR.Get(SRID.RelativeSourceModeIsImmutable)); 
                } 
            }
        } 

        ///  The Type of ancestor to look for, in FindAncestor mode.
        /// 
        ///  if Mode has not been set explicitly, setting AncestorType will implicitly lock Mode to FindAncestor.  
        ///  RelativeSource is not in FindAncestor mode 
        public Type AncestorType 
        { 
            get { return _ancestorType; }
            set 
            {
                if (IsUninitialized)
                {
                    Debug.Assert(_mode == RelativeSourceMode.FindAncestor); 
                    AncestorLevel = 1;  // lock the mode and set default level
                } 
 
                if (_mode != RelativeSourceMode.FindAncestor)
                { 
                    // in all other modes, AncestorType should not get set to a non-null value
                    if (value != null)
                        throw new InvalidOperationException(SR.Get(SRID.RelativeSourceNotInFindAncestorMode));
                } 
                else
                { 
                    _ancestorType = value; 
                }
            } 
        }

        /// 
        /// This method is used by TypeDescriptor to determine if this property should 
        /// be serialized.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public bool ShouldSerializeAncestorType()
        { 
            return (_mode == RelativeSourceMode.FindAncestor);
        }

        ///  The level of ancestor to look for, in FindAncestor mode.  Use 1 to indicate the one nearest to the target element. 
        /// 
        ///  if Mode has not been set explicitly, getting AncestorLevel will return -1 and 
        /// setting AncestorLevel will implicitly lock Mode to FindAncestor.  
        ///  RelativeSource is not in FindAncestor mode 
        ///  AncestorLevel cannot be set to less than 1  
        public int AncestorLevel
        {
            get { return _ancestorLevel; }
            set 
            {
                Debug.Assert((!IsUninitialized) || (_mode == RelativeSourceMode.FindAncestor)); 
 
                if (_mode != RelativeSourceMode.FindAncestor)
                { 
                    // in all other modes, AncestorLevel should not get set to a non-zero value
                    if (value != 0)
                        throw new InvalidOperationException(SR.Get(SRID.RelativeSourceNotInFindAncestorMode));
                } 
                else if (value < 1)
                { 
                    throw new ArgumentOutOfRangeException(SR.Get(SRID.RelativeSourceInvalidAncestorLevel)); 
                }
                else 
                {
                    _ancestorLevel = value;
                }
            } 
        }
 
        ///  
        /// This method is used by TypeDescriptor to determine if this property should
        /// be serialized. 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeAncestorLevel()
        { 
            return (_mode == RelativeSourceMode.FindAncestor);
        } 
 
#endregion public properties
 
#region public methods

        /// 
        ///  Return an object that should be set on the targetObject's targetProperty 
        ///  for this markup extension.
        ///  
        /// ServiceProvider that can be queried for services. 
        /// 
        ///  The object to set on this property. 
        /// 
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_mode == RelativeSourceMode.PreviousData) 
                return PreviousData;
            if (_mode == RelativeSourceMode.Self) 
                return Self; 
            if (_mode == RelativeSourceMode.TemplatedParent)
                return TemplatedParent; 
            return this;
        }

#endregion public methods 

#region private properties 
        private bool IsUninitialized 
        {
            get { return (_ancestorLevel == -1); } 
        }
#endregion private properties

#region private methods 
        void InitializeMode(RelativeSourceMode mode)
        { 
            Debug.Assert(IsUninitialized); 

            if (mode == RelativeSourceMode.FindAncestor) 
            {
                // default level
                _ancestorLevel = 1;
                _mode = mode; 
            }
            else if (mode == RelativeSourceMode.PreviousData 
                || mode == RelativeSourceMode.Self 
                || mode == RelativeSourceMode.TemplatedParent)
            { 
                _ancestorLevel = 0;
                _mode = mode;
            }
            else 
            {
                throw new ArgumentException(SR.Get(SRID.RelativeSourceModeInvalid), "mode"); 
            } 
        }
#endregion private methods 

#region private fields

        private RelativeSourceMode _mode; 
        private Type _ancestorType;
        private int _ancestorLevel = -1;    // while -1, indicates _mode has not been set 
 
        private static RelativeSource s_previousData;
        private static RelativeSource s_templatedParent; 
        private static RelativeSource s_self;
#endregion private fields
    }
 
}

// 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