ObjectRef.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 / MS / Internal / Data / ObjectRef.cs / 1 / ObjectRef.cs

                             
//----------------------------------------------------------------------------
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved. 
// 
// 
// Description: ObjectRef is a general way to name objects used in data binding 
//
// See spec at http://avalon/connecteddata/Specs/Data%20Binding.mht 
//
//---------------------------------------------------------------------------

using System; 
using System.Collections;
using System.Diagnostics; 
using System.Globalization; 
using System.Reflection;
using System.Windows; 
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup; 
using MS.Internal;
using MS.Internal.Utility; 
 
namespace MS.Internal.Data
{ 

#region ObjectRef
    ///  Abstract object reference. 
    internal abstract class ObjectRef 
    {
        //----------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-----------------------------------------------------

        ///  Constructor is protected - you can only create subclasses. 
        protected ObjectRef() {} 

        //------------------------------------------------------ 
        // 
        //  Public Methods
        // 
        //-----------------------------------------------------

        ///  Returns the referenced object. 
        /// Element defining context for the reference.  
        /// Is extended tracing enabled. 
        internal virtual object GetObject(DependencyObject d, bool isTracing) 
        { 
            return null;
        } 

        ///  Returns the data object associated with the referenced object.
        /// Often this is the same as the referenced object.
        ///  
        /// Element defining context for the reference. 
        /// Is extended tracing enabled.  
        ///  d is a null reference  
        internal virtual object GetDataObject(DependencyObject d, bool isTracing)
        { 
            return GetObject(d, isTracing);
        }

        ///  Returns the data object associated with the referenced object. 
        /// Often this is the same as the referenced object.
        ///  
        /// Element defining context for the reference.  
        /// If true, element name references are looked
        /// Is extended tracing enabled.  
        /// up in the target's template (if any) first. 
        ///  d is a null reference 
        internal virtual object GetDataObject(DependencyObject d, bool isTracing, bool resolveNamesInTemplate)
        { 
            return GetDataObject(d, isTracing);
        } 
 
        ///  true if the ObjectRef really needs the tree context 
        internal bool TreeContextIsRequired(DependencyObject target) 
        {
            return ProtectedTreeContextIsRequired(target);
        }
 
        ///  true if the ObjectRef really needs the tree context 
        protected virtual bool ProtectedTreeContextIsRequired(DependencyObject target) 
        { 
            return false;
        } 

        /// 
        /// true if the ObjectRef uses the mentor of the target element,
        /// rather than the target element itself. 
        /// 
        internal bool UsesMentor 
        { 
            get { return ProtectedUsesMentor; }
        } 

        /// 
        /// true if the ObjectRef uses the mentor of the target element,
        /// rather than the target element itself. 
        /// 
        protected virtual bool ProtectedUsesMentor 
        { 
            get { return true; }
        } 

        /// 
        /// identify this ObjectRef to the user - used by extended tracing
        ///  
        internal abstract string Identify();
    } 
 
#endregion ObjectRef
 
#region ElementObjectRef
    ///  Object reference to a DependencyObject via its Name. 
    internal sealed class ElementObjectRef : ObjectRef
    { 
        //------------------------------------------------------
        // 
        //  Constructors 
        //
        //------------------------------------------------------ 

        ///  Constructor. 
        /// Name of the referenced Element.
        ///  name is a null reference  
        internal ElementObjectRef(string name)
        { 
            if (name == null) 
                throw new ArgumentNullException("name");
 
            _name = name.Trim();
        }

        //----------------------------------------------------- 
        //
        //  Public Methods 
        // 
        //------------------------------------------------------
 
        ///  Returns the referenced object. 
        /// Element defining context for the reference. 
        /// Is extended tracing enabled. 
        internal override object GetObject(DependencyObject d, bool isTracing) 
        {
            return GetDataObjectImpl(d, false /* resolveNamesInTemplate */, isTracing); 
        } 

        ///  Returns the data object associated with the referenced object. 
        /// Often this is the same as the referenced object.
        /// 
        /// Element defining context for the reference. 
        /// If true, element name references are looked 
        /// Is extended tracing enabled. 
        /// up in the target's template (if any) first.  
        ///  d is a null reference  
        internal override object GetDataObject(DependencyObject d, bool isTracing, bool resolveNamesInTemplate)
        { 
            return GetDataObjectImpl(d, resolveNamesInTemplate, isTracing);
        }

        object GetDataObjectImpl(DependencyObject d, bool resolveNamesInTemplate, bool isTracing) 
        {
            if (d == null) 
                throw new ArgumentNullException("d"); 

            object o = null; 
            if (resolveNamesInTemplate)
            {
                // look in container's template (if any) first
                FrameworkElement fe = d as FrameworkElement; 
                if (fe != null && fe.TemplateInternal != null)
                { 
                    o = Helper.FindNameInTemplate(_name, d); 

                    if (isTracing) 
                    {
                        TraceData.Trace(TraceEventType.Warning,
                                            TraceData.ElementNameQueryTemplate(
                                                _name, 
                                                TraceData.Identify(d)));
                    } 
                } 
            }
 
            FrameworkObject fo = new FrameworkObject(d);
            while (o == null && fo.DO != null)
            {
                DependencyObject scopeOwner; 
                o = fo.FindName(_name, out scopeOwner);
 
                // if the original element is a scope owner, supports IComponentConnector, 
                // and has a parent, don't use the result of FindName.  The
                // element is probably an instance of a Xaml-subclassed control; 
                // we want to resolve the name starting in the next outer scope.
                // (bug 1669408)
                // Also, if the element's NavigationService property is locally
                // set, the element is the root of a navigation and should use the 
                // inner scope (bug 1765041)
                if (d == scopeOwner && d is IComponentConnector && 
                    d.ReadLocalValue(System.Windows.Navigation.NavigationService.NavigationServiceProperty) == DependencyProperty.UnsetValue) 
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(d); 
                    if (parent == null)
                    {
                        parent = Helper.FindMentor(d.InheritanceContext);
                    } 

                    if (parent != null) 
                    { 
                        o = null;
                        fo.Reset(parent); 
                        continue;
                    }
                }
 
                if (isTracing)
                { 
                    TraceData.Trace(TraceEventType.Warning, 
                                        TraceData.ElementNameQuery(
                                            _name, 
                                            TraceData.Identify(fo.DO)));
                }

                if (o == null) 
                {
                    // move to the next outer namescope. 
                    // First try TemplatedParent of the scope owner. 
                    FrameworkObject foScopeOwner = new FrameworkObject(scopeOwner);
                    DependencyObject dd = foScopeOwner.TemplatedParent; 

                    // if that doesn't work, we could be at the top of
                    // generated content for an ItemsControl.  If so, use
                    // the (visual) parent - a panel. 
                    if (dd == null)
                    { 
                        Panel panel = fo.FrameworkParent.DO as Panel; 
                        if (panel != null && panel.IsItemsHost)
                        { 
                            dd = panel;
                        }
                    }
 
                    fo.Reset(dd);
                } 
            } 

            return (o != null) ? o : DependencyProperty.UnsetValue; 
        }

        public override string ToString()
        { 
            return String.Format(CultureInfo.InvariantCulture,
                    "ElementName={0}", _name); 
        } 

        internal override string Identify() 
        {
            return "ElementName";
        }
 
        //-----------------------------------------------------
        // 
        //  Private Fields 
        //
        //----------------------------------------------------- 

        string _name;
    }
 
#endregion ElementObjectRef
 
#region RelativeObjectRef 
    ///  Object reference relative to the target element.
    ///  
    internal sealed class RelativeObjectRef : ObjectRef
    {
        //-----------------------------------------------------
        // 
        //  Constructors
        // 
        //------------------------------------------------------ 

        ///  Constructor.  
        /// RelativeSource. 
        ///  relativeSource is a null reference 
        internal RelativeObjectRef(RelativeSource relativeSource)
        { 
            if (relativeSource == null)
                throw new ArgumentNullException("relativeSource"); 
 
            _relativeSource = relativeSource;
        } 

        //-----------------------------------------------------
        //
        //  Public Methods 
        //
        //------------------------------------------------------ 
 
        public override string ToString()
        { 
            string s;
            switch (_relativeSource.Mode)
            {
                case RelativeSourceMode.FindAncestor: 
                    s = String.Format(CultureInfo.InvariantCulture,
                        "RelativeSource {0}, AncestorType='{1}', AncestorLevel='{2}'", 
                        _relativeSource.Mode, 
                        _relativeSource.AncestorType,
                        _relativeSource.AncestorLevel); 
                    break;
                default:
                    s = String.Format(CultureInfo.InvariantCulture,
                        "RelativeSource {0}", _relativeSource.Mode); 
                    break;
            } 
 
            return s;
        } 

        ///  Returns the referenced object. 
        /// Element defining context for the reference. 
        /// Is extended tracing enabled.  
        ///  d is a null reference 
        internal override object GetObject(DependencyObject d, bool isTracing) 
        { 
            return GetDataObjectImpl(d, isTracing);
        } 

        ///  Returns the data object associated with the referenced object.
        /// Often this is the same as the referenced object.
        ///  
        /// Element defining context for the reference. 
        /// If true, element name references are looked 
        /// Is extended tracing enabled.  
        /// up in the target's template (if any) first. 
        ///  d is a null reference  
        internal override object GetDataObject(DependencyObject d, bool isTracing, bool resolveNamesInTemplate)
        {
            object o = GetDataObjectImpl(d, isTracing);
            DependencyObject el = o as DependencyObject; 

            if (el != null && ReturnsDataContext) 
            { 
                // for generated wrappers, use the ItemForContainer property instead
                // of DataContext, since it's always set by the generator 
                o = el.GetValue(ItemContainerGenerator.ItemForItemContainerProperty);
                if (o == null)
                    o = el.GetValue(FrameworkElement.DataContextProperty);
            } 

            return o; 
        } 

        private object GetDataObjectImpl(DependencyObject d, bool isTracing) 
        {
            if (d == null)
                return null;
 
            switch (_relativeSource.Mode)
            { 
                case RelativeSourceMode.Self: 
                    break;              // nothing to do
 
                case RelativeSourceMode.TemplatedParent:
                    d = Helper.GetTemplatedParent(d);
                    break;
 
                case RelativeSourceMode.PreviousData:
                    return GetPreviousData(d); 
 
                case RelativeSourceMode.FindAncestor:
                    d = FindAncestorOfType(_relativeSource.AncestorType, _relativeSource.AncestorLevel, d, isTracing); 
                    if (d == null)
                    {
                        return DependencyProperty.UnsetValue;   // we fell off the tree
                    } 
                    break;
 
                default: 
                    return null;
            } 

            if (isTracing)
            {
                TraceData.Trace(TraceEventType.Warning, 
                                    TraceData.RelativeSource(
                                        _relativeSource.Mode, 
                                        TraceData.Identify(d))); 
            }
 
            return d;
        }

        internal bool ReturnsDataContext 
        {
            get { return (_relativeSource.Mode == RelativeSourceMode.PreviousData); } 
        } 

        ///  true if the ObjectRef really needs the tree context  
        protected override bool ProtectedTreeContextIsRequired(DependencyObject target)
        {
            return  (   (_relativeSource.Mode == RelativeSourceMode.FindAncestor
                    ||  (_relativeSource.Mode == RelativeSourceMode.PreviousData))); 
        }
 
        protected override bool ProtectedUsesMentor 
        {
            get 
            {
                switch (_relativeSource.Mode)
                {
                    case RelativeSourceMode.TemplatedParent: 
                    case RelativeSourceMode.PreviousData:
                        return true; 
 
                    default:
                        return false; 
                }
            }
        }
 
        internal override string Identify()
        { 
            return String.Format(DataBindEngine.EnglishUSCulture, 
                "RelativeSource ({0})", _relativeSource.Mode);
        } 

        //------------------------------------------------------
        //
        //  Private Method 
        //
        //----------------------------------------------------- 
 
        private object GetPreviousData(DependencyObject d)
        { 
            // move up to the next containing DataContext scope
            for (; d != null; d = FrameworkElement.GetFrameworkParent(d))
            {
                if (BindingExpression.HasLocalDataContext(d)) 
                {
                    // special case:  if the element is a ContentPresenter 
                    // whose templated parent is a ContentControl or 
                    // HeaderedItemsControl, and both have the same
                    // DataContext, we'll use the parent instead of the 
                    // ContentPresenter.  In this case, the DataContext
                    // of the CP is set by various forwarding rules, and
                    // shouldn't count as a new scope.
                    ContentPresenter cp = d as ContentPresenter; 
                    FrameworkElement parent;
                    if (cp != null && (parent = cp.TemplatedParent as FrameworkElement) != null) 
                    { 
                        if ((parent is ContentControl || parent is HeaderedItemsControl) &&
                            Object.Equals(cp.DataContext, parent.DataContext)) 
                        {
                            d = parent;
                            if (!BindingExpression.HasLocalDataContext(parent))
                            { 
                                continue;
                            } 
                        } 
                    }
 
                    break;
                }
            }
 
            if (d == null)
                return DependencyProperty.UnsetValue;   // we fell off the tree 
 
            // this only makes sense within generated content.  If this
            // is the case, then d is now the wrapper element, its visual 
            // parent is the layout element, and the layout's ItemsOwner
            // is the govening ItemsControl.
            Visual v = d as Visual;
            DependencyObject layout = (v != null) ? VisualTreeHelper.GetParent(v) : null; 
            ItemsControl ic = ItemsControl.GetItemsOwner(layout);
            if (ic == null) 
            { 
                if (TraceData.IsEnabled)
                    TraceData.Trace(TraceEventType.Error, TraceData.RefPreviousNotInContext); 
                return null;
            }

            // now look up the wrapper's previous sibling within the 
            // layout's children collection
            Visual v2 = layout as Visual; 
            int count = (v2 != null) ? v2.InternalVisualChildrenCount : 0; 
            int j = -1;
            Visual prevChild = null;   //child at j-1th index 
            if (count != 0)
            {
                j = IndexOf(v2, v, out prevChild);
            } 
            if (j > 0)
            { 
                d = prevChild; 
            }
            else 
            {
                d = null;
                if ((j < 0) && TraceData.IsEnabled)
                    TraceData.Trace(TraceEventType.Error, TraceData.RefNoWrapperInChildren); 
            }
            return d; 
        } 

        private DependencyObject FindAncestorOfType(Type type, int level, DependencyObject d, bool isTracing) 
        {
            if (type == null)
            {
                if (TraceData.IsEnabled) 
                    TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorTypeNotSpecified);
                return null; 
            } 
            if (level < 1)
            { 
                if (TraceData.IsEnabled)
                    TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorLevelInvalid);
                return null;
            } 

            // initialize search to start at the parent of the given DO 
            FrameworkObject fo = new FrameworkObject(d); 
            fo.Reset(fo.GetPreferVisualParent(true).DO);
 
            while (fo.DO != null)
            {
                if (isTracing)
                { 
                    TraceData.Trace(TraceEventType.Warning,
                                        TraceData.AncestorLookup( 
                                            type.Name, 
                                            TraceData.Identify(fo.DO)));
                } 

                if (type.IsInstanceOfType(fo.DO))   // found it!
                {
                    if (--level <= 0) 
                        break;
                } 
 
                fo.Reset(fo.PreferVisualParent.DO);
            } 

            return fo.DO;
        }
 
        private int IndexOf(Visual parent, Visual child, out Visual prevChild)
        { 
            Visual temp; 
            bool foundIndex = false;
            prevChild = null; 
            int count = parent.InternalVisualChildrenCount;
            int i;
            for(i = 0; i < count; i++)
            { 
                temp = parent.InternalGetVisualChild(i);
                if(child == temp) 
                { 
                    foundIndex = true;
                    break; 
                }
                prevChild = temp;
            }
            if (foundIndex) return i; 
            else return -1;
        } 
 
        //------------------------------------------------------
        // 
        //  Private Fields
        //
        //-----------------------------------------------------
 
        RelativeSource _relativeSource;
    } 
 
#endregion RelativeObjectRef
 
#region ExplicitObjectRef
    ///  Explicit object reference. 
    internal sealed class ExplicitObjectRef: ObjectRef
    { 
        //-----------------------------------------------------
        // 
        //  Constructors 
        //
        //----------------------------------------------------- 

        ///  Constructor. 
        internal ExplicitObjectRef(object o)
        { 
            if (o is DependencyObject)
                _element = new WeakReference(o); 
            else 
                _object = o;
        } 

        //------------------------------------------------------
        //
        //  Public Methods 
        //
        //----------------------------------------------------- 
 
        ///  Returns the referenced object. 
        /// Element defining context for the reference.  
        /// Is extended tracing enabled. 
        internal override object GetObject(DependencyObject d, bool isTracing)
        {
            return (_element != null) ? _element.Target : _object; 
        }
 
        ///  
        /// true if the ObjectRef uses the mentor of the target element,
        /// rather than the target element itself. 
        /// 
        protected override bool ProtectedUsesMentor
        {
            get { return false; } 
        }
 
        internal override string Identify() 
        {
            return "Source"; 
        }

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

        object _object; 
        WeakReference _element; // to DependencyObject (bug 986435)
    }

#endregion ExplicitObjectRef 

} 
 


// 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: ObjectRef is a general way to name objects used in data binding 
//
// See spec at http://avalon/connecteddata/Specs/Data%20Binding.mht 
//
//---------------------------------------------------------------------------

using System; 
using System.Collections;
using System.Diagnostics; 
using System.Globalization; 
using System.Reflection;
using System.Windows; 
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup; 
using MS.Internal;
using MS.Internal.Utility; 
 
namespace MS.Internal.Data
{ 

#region ObjectRef
    ///  Abstract object reference. 
    internal abstract class ObjectRef 
    {
        //----------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-----------------------------------------------------

        ///  Constructor is protected - you can only create subclasses. 
        protected ObjectRef() {} 

        //------------------------------------------------------ 
        // 
        //  Public Methods
        // 
        //-----------------------------------------------------

        ///  Returns the referenced object. 
        /// Element defining context for the reference.  
        /// Is extended tracing enabled. 
        internal virtual object GetObject(DependencyObject d, bool isTracing) 
        { 
            return null;
        } 

        ///  Returns the data object associated with the referenced object.
        /// Often this is the same as the referenced object.
        ///  
        /// Element defining context for the reference. 
        /// Is extended tracing enabled.  
        ///  d is a null reference  
        internal virtual object GetDataObject(DependencyObject d, bool isTracing)
        { 
            return GetObject(d, isTracing);
        }

        ///  Returns the data object associated with the referenced object. 
        /// Often this is the same as the referenced object.
        ///  
        /// Element defining context for the reference.  
        /// If true, element name references are looked
        /// Is extended tracing enabled.  
        /// up in the target's template (if any) first. 
        ///  d is a null reference 
        internal virtual object GetDataObject(DependencyObject d, bool isTracing, bool resolveNamesInTemplate)
        { 
            return GetDataObject(d, isTracing);
        } 
 
        ///  true if the ObjectRef really needs the tree context 
        internal bool TreeContextIsRequired(DependencyObject target) 
        {
            return ProtectedTreeContextIsRequired(target);
        }
 
        ///  true if the ObjectRef really needs the tree context 
        protected virtual bool ProtectedTreeContextIsRequired(DependencyObject target) 
        { 
            return false;
        } 

        /// 
        /// true if the ObjectRef uses the mentor of the target element,
        /// rather than the target element itself. 
        /// 
        internal bool UsesMentor 
        { 
            get { return ProtectedUsesMentor; }
        } 

        /// 
        /// true if the ObjectRef uses the mentor of the target element,
        /// rather than the target element itself. 
        /// 
        protected virtual bool ProtectedUsesMentor 
        { 
            get { return true; }
        } 

        /// 
        /// identify this ObjectRef to the user - used by extended tracing
        ///  
        internal abstract string Identify();
    } 
 
#endregion ObjectRef
 
#region ElementObjectRef
    ///  Object reference to a DependencyObject via its Name. 
    internal sealed class ElementObjectRef : ObjectRef
    { 
        //------------------------------------------------------
        // 
        //  Constructors 
        //
        //------------------------------------------------------ 

        ///  Constructor. 
        /// Name of the referenced Element.
        ///  name is a null reference  
        internal ElementObjectRef(string name)
        { 
            if (name == null) 
                throw new ArgumentNullException("name");
 
            _name = name.Trim();
        }

        //----------------------------------------------------- 
        //
        //  Public Methods 
        // 
        //------------------------------------------------------
 
        ///  Returns the referenced object. 
        /// Element defining context for the reference. 
        /// Is extended tracing enabled. 
        internal override object GetObject(DependencyObject d, bool isTracing) 
        {
            return GetDataObjectImpl(d, false /* resolveNamesInTemplate */, isTracing); 
        } 

        ///  Returns the data object associated with the referenced object. 
        /// Often this is the same as the referenced object.
        /// 
        /// Element defining context for the reference. 
        /// If true, element name references are looked 
        /// Is extended tracing enabled. 
        /// up in the target's template (if any) first.  
        ///  d is a null reference  
        internal override object GetDataObject(DependencyObject d, bool isTracing, bool resolveNamesInTemplate)
        { 
            return GetDataObjectImpl(d, resolveNamesInTemplate, isTracing);
        }

        object GetDataObjectImpl(DependencyObject d, bool resolveNamesInTemplate, bool isTracing) 
        {
            if (d == null) 
                throw new ArgumentNullException("d"); 

            object o = null; 
            if (resolveNamesInTemplate)
            {
                // look in container's template (if any) first
                FrameworkElement fe = d as FrameworkElement; 
                if (fe != null && fe.TemplateInternal != null)
                { 
                    o = Helper.FindNameInTemplate(_name, d); 

                    if (isTracing) 
                    {
                        TraceData.Trace(TraceEventType.Warning,
                                            TraceData.ElementNameQueryTemplate(
                                                _name, 
                                                TraceData.Identify(d)));
                    } 
                } 
            }
 
            FrameworkObject fo = new FrameworkObject(d);
            while (o == null && fo.DO != null)
            {
                DependencyObject scopeOwner; 
                o = fo.FindName(_name, out scopeOwner);
 
                // if the original element is a scope owner, supports IComponentConnector, 
                // and has a parent, don't use the result of FindName.  The
                // element is probably an instance of a Xaml-subclassed control; 
                // we want to resolve the name starting in the next outer scope.
                // (bug 1669408)
                // Also, if the element's NavigationService property is locally
                // set, the element is the root of a navigation and should use the 
                // inner scope (bug 1765041)
                if (d == scopeOwner && d is IComponentConnector && 
                    d.ReadLocalValue(System.Windows.Navigation.NavigationService.NavigationServiceProperty) == DependencyProperty.UnsetValue) 
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(d); 
                    if (parent == null)
                    {
                        parent = Helper.FindMentor(d.InheritanceContext);
                    } 

                    if (parent != null) 
                    { 
                        o = null;
                        fo.Reset(parent); 
                        continue;
                    }
                }
 
                if (isTracing)
                { 
                    TraceData.Trace(TraceEventType.Warning, 
                                        TraceData.ElementNameQuery(
                                            _name, 
                                            TraceData.Identify(fo.DO)));
                }

                if (o == null) 
                {
                    // move to the next outer namescope. 
                    // First try TemplatedParent of the scope owner. 
                    FrameworkObject foScopeOwner = new FrameworkObject(scopeOwner);
                    DependencyObject dd = foScopeOwner.TemplatedParent; 

                    // if that doesn't work, we could be at the top of
                    // generated content for an ItemsControl.  If so, use
                    // the (visual) parent - a panel. 
                    if (dd == null)
                    { 
                        Panel panel = fo.FrameworkParent.DO as Panel; 
                        if (panel != null && panel.IsItemsHost)
                        { 
                            dd = panel;
                        }
                    }
 
                    fo.Reset(dd);
                } 
            } 

            return (o != null) ? o : DependencyProperty.UnsetValue; 
        }

        public override string ToString()
        { 
            return String.Format(CultureInfo.InvariantCulture,
                    "ElementName={0}", _name); 
        } 

        internal override string Identify() 
        {
            return "ElementName";
        }
 
        //-----------------------------------------------------
        // 
        //  Private Fields 
        //
        //----------------------------------------------------- 

        string _name;
    }
 
#endregion ElementObjectRef
 
#region RelativeObjectRef 
    ///  Object reference relative to the target element.
    ///  
    internal sealed class RelativeObjectRef : ObjectRef
    {
        //-----------------------------------------------------
        // 
        //  Constructors
        // 
        //------------------------------------------------------ 

        ///  Constructor.  
        /// RelativeSource. 
        ///  relativeSource is a null reference 
        internal RelativeObjectRef(RelativeSource relativeSource)
        { 
            if (relativeSource == null)
                throw new ArgumentNullException("relativeSource"); 
 
            _relativeSource = relativeSource;
        } 

        //-----------------------------------------------------
        //
        //  Public Methods 
        //
        //------------------------------------------------------ 
 
        public override string ToString()
        { 
            string s;
            switch (_relativeSource.Mode)
            {
                case RelativeSourceMode.FindAncestor: 
                    s = String.Format(CultureInfo.InvariantCulture,
                        "RelativeSource {0}, AncestorType='{1}', AncestorLevel='{2}'", 
                        _relativeSource.Mode, 
                        _relativeSource.AncestorType,
                        _relativeSource.AncestorLevel); 
                    break;
                default:
                    s = String.Format(CultureInfo.InvariantCulture,
                        "RelativeSource {0}", _relativeSource.Mode); 
                    break;
            } 
 
            return s;
        } 

        ///  Returns the referenced object. 
        /// Element defining context for the reference. 
        /// Is extended tracing enabled.  
        ///  d is a null reference 
        internal override object GetObject(DependencyObject d, bool isTracing) 
        { 
            return GetDataObjectImpl(d, isTracing);
        } 

        ///  Returns the data object associated with the referenced object.
        /// Often this is the same as the referenced object.
        ///  
        /// Element defining context for the reference. 
        /// If true, element name references are looked 
        /// Is extended tracing enabled.  
        /// up in the target's template (if any) first. 
        ///  d is a null reference  
        internal override object GetDataObject(DependencyObject d, bool isTracing, bool resolveNamesInTemplate)
        {
            object o = GetDataObjectImpl(d, isTracing);
            DependencyObject el = o as DependencyObject; 

            if (el != null && ReturnsDataContext) 
            { 
                // for generated wrappers, use the ItemForContainer property instead
                // of DataContext, since it's always set by the generator 
                o = el.GetValue(ItemContainerGenerator.ItemForItemContainerProperty);
                if (o == null)
                    o = el.GetValue(FrameworkElement.DataContextProperty);
            } 

            return o; 
        } 

        private object GetDataObjectImpl(DependencyObject d, bool isTracing) 
        {
            if (d == null)
                return null;
 
            switch (_relativeSource.Mode)
            { 
                case RelativeSourceMode.Self: 
                    break;              // nothing to do
 
                case RelativeSourceMode.TemplatedParent:
                    d = Helper.GetTemplatedParent(d);
                    break;
 
                case RelativeSourceMode.PreviousData:
                    return GetPreviousData(d); 
 
                case RelativeSourceMode.FindAncestor:
                    d = FindAncestorOfType(_relativeSource.AncestorType, _relativeSource.AncestorLevel, d, isTracing); 
                    if (d == null)
                    {
                        return DependencyProperty.UnsetValue;   // we fell off the tree
                    } 
                    break;
 
                default: 
                    return null;
            } 

            if (isTracing)
            {
                TraceData.Trace(TraceEventType.Warning, 
                                    TraceData.RelativeSource(
                                        _relativeSource.Mode, 
                                        TraceData.Identify(d))); 
            }
 
            return d;
        }

        internal bool ReturnsDataContext 
        {
            get { return (_relativeSource.Mode == RelativeSourceMode.PreviousData); } 
        } 

        ///  true if the ObjectRef really needs the tree context  
        protected override bool ProtectedTreeContextIsRequired(DependencyObject target)
        {
            return  (   (_relativeSource.Mode == RelativeSourceMode.FindAncestor
                    ||  (_relativeSource.Mode == RelativeSourceMode.PreviousData))); 
        }
 
        protected override bool ProtectedUsesMentor 
        {
            get 
            {
                switch (_relativeSource.Mode)
                {
                    case RelativeSourceMode.TemplatedParent: 
                    case RelativeSourceMode.PreviousData:
                        return true; 
 
                    default:
                        return false; 
                }
            }
        }
 
        internal override string Identify()
        { 
            return String.Format(DataBindEngine.EnglishUSCulture, 
                "RelativeSource ({0})", _relativeSource.Mode);
        } 

        //------------------------------------------------------
        //
        //  Private Method 
        //
        //----------------------------------------------------- 
 
        private object GetPreviousData(DependencyObject d)
        { 
            // move up to the next containing DataContext scope
            for (; d != null; d = FrameworkElement.GetFrameworkParent(d))
            {
                if (BindingExpression.HasLocalDataContext(d)) 
                {
                    // special case:  if the element is a ContentPresenter 
                    // whose templated parent is a ContentControl or 
                    // HeaderedItemsControl, and both have the same
                    // DataContext, we'll use the parent instead of the 
                    // ContentPresenter.  In this case, the DataContext
                    // of the CP is set by various forwarding rules, and
                    // shouldn't count as a new scope.
                    ContentPresenter cp = d as ContentPresenter; 
                    FrameworkElement parent;
                    if (cp != null && (parent = cp.TemplatedParent as FrameworkElement) != null) 
                    { 
                        if ((parent is ContentControl || parent is HeaderedItemsControl) &&
                            Object.Equals(cp.DataContext, parent.DataContext)) 
                        {
                            d = parent;
                            if (!BindingExpression.HasLocalDataContext(parent))
                            { 
                                continue;
                            } 
                        } 
                    }
 
                    break;
                }
            }
 
            if (d == null)
                return DependencyProperty.UnsetValue;   // we fell off the tree 
 
            // this only makes sense within generated content.  If this
            // is the case, then d is now the wrapper element, its visual 
            // parent is the layout element, and the layout's ItemsOwner
            // is the govening ItemsControl.
            Visual v = d as Visual;
            DependencyObject layout = (v != null) ? VisualTreeHelper.GetParent(v) : null; 
            ItemsControl ic = ItemsControl.GetItemsOwner(layout);
            if (ic == null) 
            { 
                if (TraceData.IsEnabled)
                    TraceData.Trace(TraceEventType.Error, TraceData.RefPreviousNotInContext); 
                return null;
            }

            // now look up the wrapper's previous sibling within the 
            // layout's children collection
            Visual v2 = layout as Visual; 
            int count = (v2 != null) ? v2.InternalVisualChildrenCount : 0; 
            int j = -1;
            Visual prevChild = null;   //child at j-1th index 
            if (count != 0)
            {
                j = IndexOf(v2, v, out prevChild);
            } 
            if (j > 0)
            { 
                d = prevChild; 
            }
            else 
            {
                d = null;
                if ((j < 0) && TraceData.IsEnabled)
                    TraceData.Trace(TraceEventType.Error, TraceData.RefNoWrapperInChildren); 
            }
            return d; 
        } 

        private DependencyObject FindAncestorOfType(Type type, int level, DependencyObject d, bool isTracing) 
        {
            if (type == null)
            {
                if (TraceData.IsEnabled) 
                    TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorTypeNotSpecified);
                return null; 
            } 
            if (level < 1)
            { 
                if (TraceData.IsEnabled)
                    TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorLevelInvalid);
                return null;
            } 

            // initialize search to start at the parent of the given DO 
            FrameworkObject fo = new FrameworkObject(d); 
            fo.Reset(fo.GetPreferVisualParent(true).DO);
 
            while (fo.DO != null)
            {
                if (isTracing)
                { 
                    TraceData.Trace(TraceEventType.Warning,
                                        TraceData.AncestorLookup( 
                                            type.Name, 
                                            TraceData.Identify(fo.DO)));
                } 

                if (type.IsInstanceOfType(fo.DO))   // found it!
                {
                    if (--level <= 0) 
                        break;
                } 
 
                fo.Reset(fo.PreferVisualParent.DO);
            } 

            return fo.DO;
        }
 
        private int IndexOf(Visual parent, Visual child, out Visual prevChild)
        { 
            Visual temp; 
            bool foundIndex = false;
            prevChild = null; 
            int count = parent.InternalVisualChildrenCount;
            int i;
            for(i = 0; i < count; i++)
            { 
                temp = parent.InternalGetVisualChild(i);
                if(child == temp) 
                { 
                    foundIndex = true;
                    break; 
                }
                prevChild = temp;
            }
            if (foundIndex) return i; 
            else return -1;
        } 
 
        //------------------------------------------------------
        // 
        //  Private Fields
        //
        //-----------------------------------------------------
 
        RelativeSource _relativeSource;
    } 
 
#endregion RelativeObjectRef
 
#region ExplicitObjectRef
    ///  Explicit object reference. 
    internal sealed class ExplicitObjectRef: ObjectRef
    { 
        //-----------------------------------------------------
        // 
        //  Constructors 
        //
        //----------------------------------------------------- 

        ///  Constructor. 
        internal ExplicitObjectRef(object o)
        { 
            if (o is DependencyObject)
                _element = new WeakReference(o); 
            else 
                _object = o;
        } 

        //------------------------------------------------------
        //
        //  Public Methods 
        //
        //----------------------------------------------------- 
 
        ///  Returns the referenced object. 
        /// Element defining context for the reference.  
        /// Is extended tracing enabled. 
        internal override object GetObject(DependencyObject d, bool isTracing)
        {
            return (_element != null) ? _element.Target : _object; 
        }
 
        ///  
        /// true if the ObjectRef uses the mentor of the target element,
        /// rather than the target element itself. 
        /// 
        protected override bool ProtectedUsesMentor
        {
            get { return false; } 
        }
 
        internal override string Identify() 
        {
            return "Source"; 
        }

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

        object _object; 
        WeakReference _element; // to DependencyObject (bug 986435)
    }

#endregion ExplicitObjectRef 

} 
 


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