DataIdProcessor.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / Annotations / Anchoring / DataIdProcessor.cs / 1 / DataIdProcessor.cs

                            #pragma warning disable 1634, 1691 
//------------------------------------------------------------------------------
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved. 
// 
// 
// Description: 
//     DataIdProcessor walks the tree and loads annotations based on unique ids
//     identified by the DataIdProperty.  It loads annotations when it 
//     reaches a leaf in the tree or when it runs into a node with the
//     FetchAnnotationsAsBatch property set to true.
//     Spec: http://team/sites/ag/Specifications/Anchoring%20Namespace%20Spec.doc
// 
// History:
//  12/01/2002: magedz: Created - based on architectural discussions and design 
//                      by axelk, rruiz, magedz 
//  07/22/2003: rruiz:  Ported to WCP
//  08/18/2003: rruiz:  Updated to Anchoring Namespace Spec. 
//
//-----------------------------------------------------------------------------

using System; 
using System.Diagnostics;
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel;
using System.Windows; 
using System.Windows.Annotations;
using System.Windows.Annotations.Storage;
using System.Windows.Markup;
using System.Windows.Threading; 
using System.Xml;
 
using MS.Utility; 

namespace MS.Internal.Annotations.Anchoring 
{
    /// 
    ///     DataIdProcessor walks the tree and loads annotations based on unique ids
    ///     identified by the DataIdProperty.  It loads annotations when it 
    ///     reaches a leaf in the tree or when it runs into a node with the
    ///     FetchAnnotationsAsBatch property set to true. 
    ///  
    internal sealed class DataIdProcessor : SubTreeProcessor
    { 
        //-----------------------------------------------------
        //
        //  Constructors
        // 
        //-----------------------------------------------------
 
        #region Constructors 

        ///  
        ///     Creates an instance of DataIdProcessor.
        /// 
        /// the manager that owns this processor
        /// manager is null 
        public DataIdProcessor(LocatorManager manager) : base(manager)
        { 
        } 

        #endregion Constructors 

        //------------------------------------------------------
        //
        //  Public Methods 
        //
        //----------------------------------------------------- 
 
        #region Public Methods
 
        /// 
        ///     If and only if the current node has a DataId set and has FetchAnnotationsAsBatch
        ///     set to true, then all annotations for the subtree rooted at this node are loaded
        ///     at once. 
        /// 
        /// node to process 
        /// indicates the callback was called by 
        /// this processor
        ///  
        ///     a list of AttachedAnnotations loaded during the processing of
        ///     the node; can be null if no annotations were loaded
        /// 
        /// node is null 
        public override IList PreProcessNode(DependencyObject node, out bool calledProcessAnnotations)
        { 
            if (node == null) 
                throw new ArgumentNullException("node");
 
            // We get the local value so we can distinguish between the property
            // being set or not.  We don't want to rely on null or String.Empty because
            // those might have been the values set.
            object dataId = node.ReadLocalValue(DataIdProcessor.DataIdProperty); 
            bool fetchAsBatch = (bool) node.GetValue(FetchAnnotationsAsBatchProperty);
 
            // If the current node has an ID set on it and FetchAnnotationsAsBatch is 
            // set to true, we process this node immediately and return.  All its children
            // will be processed indirectly. 
            if (fetchAsBatch && dataId != DependencyProperty.UnsetValue)
            {
                calledProcessAnnotations = true;
                return Manager.ProcessAnnotations(node); 
            }
 
            calledProcessAnnotations = false; 
            return null;
        } 

        /// 
        ///     This method is called after PreProcessNode and after all the children
        ///     in the subtree have been processed (or skipped if PreProcessNode returns 
        ///     true for calledProcessAnnotations).
        ///     If no calls to ProcessAnnotations were made for any portion of the subtree below 
        ///     this node, then annotations for this node will be loaded 
        /// 
        /// the node to process 
        /// indicates whether calledProcessAnnotations
        /// was returned as true by any node underneath this node
        /// indicates whether ProcessAnnotations was called
        /// by this method 
        /// 
        ///     a list of AttachedAnnotations loaded during the processing of 
        ///     the node; can be null if no annotations were loaded 
        /// 
        public override IList PostProcessNode(DependencyObject node, bool childrenCalledProcessAnnotations, out bool calledProcessAnnotations) 
        {
            if (node == null)
                throw new ArgumentNullException("node");
 
            // We get the local value so we can distinguish between the property
            // being set or not.  We don't want to rely on null or String.Empty because 
            // those might have been the values set. 
            object dataId = node.ReadLocalValue(DataIdProcessor.DataIdProperty);
            bool fetchAsBatch = (bool) node.GetValue(FetchAnnotationsAsBatchProperty); 

            // If no children were processed, we try and process this node
            if (!fetchAsBatch && !childrenCalledProcessAnnotations && dataId != DependencyProperty.UnsetValue)
            { 
                FrameworkElement nodeParent = null;
                FrameworkElement feNode = node as FrameworkElement; 
                if (feNode != null) 
                {
                    nodeParent = feNode.Parent as FrameworkElement; 
                }
                AnnotationService service = AnnotationService.GetService(node);
                if (service != null &&
                    (service.Root == node || 
                    (nodeParent != null && service.Root == nodeParent.TemplatedParent)))
                { 
                    calledProcessAnnotations = true; 
                    return Manager.ProcessAnnotations(node);
                } 
            }

            calledProcessAnnotations = false;
            return null; 
        }
 
        ///  
        ///     Generates a locator part list identifying node.  If node has a
        ///     value for DataIdProperty, a locator with a single locator part 
        ///     containing the id value is returned.  Otherwise null is returned.
        /// 
        /// the node to generate a locator for
        /// specifies whether or not generating should 
        /// continue for the rest of the path; always set to true
        /// if node has a value for DataIdProperty, a locator with a 
        /// single locator part containing the id value; null otherwise 
        /// 
        /// node is null 
        public override ContentLocator GenerateLocator(PathNode node, out bool continueGenerating)
        {
            if (node == null)
                throw new ArgumentNullException("node"); 

            continueGenerating = true; 
 
            ContentLocator locator = null;
            ContentLocatorPart newLocatorPart = CreateLocatorPart(node.Node); 
            if (newLocatorPart != null)
            {
                locator = new ContentLocator();
                locator.Parts.Add(newLocatorPart); 
            }
 
            return locator; 
        }
 
        /// 
        ///     Searches the logical tree for a node matching the values of
        ///     locatorPart.  The search begins with startNode.
        ///  
        /// locator part to be matched, must be of the type
        /// handled by this processor 
        /// logical tree node to start search at 
        /// return flag indicating whether the search
        /// should continue (presumably because the search was not exhaustive) 
        /// returns a node that matches the locator part; null if no such
        /// node is found
        /// locatorPart or startNode are
        /// null 
        /// locatorPart is of the incorrect
        /// type 
        public override DependencyObject ResolveLocatorPart(ContentLocatorPart locatorPart, DependencyObject startNode, out bool continueResolving) 
        {
            if (locatorPart == null) 
                throw new ArgumentNullException("locatorPart");

            if (startNode == null)
                throw new ArgumentNullException("startNode"); 

            if (DataIdElementName != locatorPart.PartType) 
                throw new ArgumentException(SR.Get(SRID.IncorrectLocatorPartType, locatorPart.PartType.Namespace + ":" + locatorPart.PartType.Name), "locatorPart"); 

            // Initial value 
            continueResolving = true;

            // Get the values from the locator part...
            string id = locatorPart.NameValuePairs[ValueAttributeName]; 
            if(id == null)
            { 
                throw new ArgumentException(SR.Get(SRID.IncorrectLocatorPartType, locatorPart.PartType.Namespace + ":" + locatorPart.PartType.Name), "locatorPart"); 
            }
 
            // and from the node to examine.
            string nodeId = GetNodeId(startNode);

            if (nodeId != null) 
            {
                if (nodeId.Equals(id)) 
                { 
                    return startNode;
                } 
                else
                {
                    // If there was a value and it didn't match,
                    // we shouldn't bother checking the subtree 
                    continueResolving = false;
                } 
            } 

            return null; 
        }

        /// 
        ///     Returns a list of XmlQualifiedNames representing the 
        ///     the locator parts this processor can resolve/generate.
        ///  
        public override XmlQualifiedName[] GetLocatorPartTypes() 
        {
            return (XmlQualifiedName[])LocatorPartTypeNames.Clone(); 
        }

        #endregion Public Methods
 
        //------------------------------------------------------
        // 
        //  Public Operators 
        //
        //------------------------------------------------------ 

        //-----------------------------------------------------
        //
        //  Public Events 
        //
        //------------------------------------------------------ 
 
        //-----------------------------------------------------
        // 
        //  Public Properties
        //
        //-----------------------------------------------------
 
        #region Public Properties
 
        ///  
        ///     Id used to register this processor with the LocatorManager.  Registration
        ///     is done by the framework and does not need to be repeated.  Use this 
        ///     string in markup as the value for SubTreeProcessorIdProperty.
        /// 
        public const String Id = "Id";
 
        /// 
        ///     Used to specify a unique id for the data represented by a 
        ///     logical tree node.  Attach this property to the element with a 
        ///     unique value.
        ///  
#pragma warning suppress 7009
        public static readonly DependencyProperty DataIdProperty =
                DependencyProperty.RegisterAttached(
                        "DataId", 
                        typeof(String),
                        typeof(DataIdProcessor), 
                        new PropertyMetadata( 
                                (string) null,
                                new PropertyChangedCallback(OnDataIdPropertyChanged), 
                                new CoerceValueCallback(CoerceDataId)));

        /// 
        ///    Sets the value of the DataId attached property 
        ///    of the LocatorManager class.
        ///  
        /// element to which to write the attached property 
        /// the value to set
        /// d is null 
        public static void SetDataId(DependencyObject d, String id)
        {
            if(d == null)
                throw new ArgumentNullException("d"); 

            d.SetValue(DataIdProperty, id); 
        } 

        ///  
        ///    Gets the value of the DataId attached property
        ///    of the LocatorManager class.
        /// 
        /// the object from which to read the attached property 
        /// the value of the DataId attached property
        /// d is null 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public static String GetDataId(DependencyObject d)
        { 
            if (d == null)
                throw new ArgumentNullException("d");

            return d.GetValue(DataIdProperty) as String; 
        }
 
        ///  
        ///     Property that specifies, when set to true on an element, this
        ///     processor should load all annotations for the subtree rooted 
        ///     a the element as a batch.
        /// 
#pragma warning suppress 7009
        public static readonly DependencyProperty FetchAnnotationsAsBatchProperty = DependencyProperty.RegisterAttached( 
                "FetchAnnotationsAsBatch",
                typeof(bool), 
                typeof(DataIdProcessor), 
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
 
        /// 
        ///    Sets the value of the FetchAnnotationsAsBatch attached property
        ///    of the LocatorManager class.
        ///  
        /// element to which to write the attached property
        /// the value to set 
        /// d is null 
        public static void SetFetchAnnotationsAsBatch(DependencyObject d, bool id)
        { 
            if(d == null)
                throw new ArgumentNullException("d");

            d.SetValue(FetchAnnotationsAsBatchProperty, id); 
        }
 
 
        /// 
        ///    Gets the value of the FetchAnnotationsAsBatch attached property 
        ///    of the LocatorManager class.
        /// 
        /// the object from which to read the attached property
        /// the value of the FetchAnnotationsAsBatch attached property 
        /// d is null
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public static bool GetFetchAnnotationsAsBatch(DependencyObject d) 
        {
            if(d == null) 
                throw new ArgumentNullException("d");

            return (bool)d.GetValue(FetchAnnotationsAsBatchProperty);
        } 

        #endregion Public Properties 
 
        //-----------------------------------------------------
        // 
        //  Private Methods
        //
        //------------------------------------------------------
 
        #region Private Methods
 
        ///  
        ///    Callback triggered when a DataIdProperty value changes.
        ///    If the values are really different we unload and reload annotations 
        ///    using the new value.
        /// 
        private static void OnDataIdPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            String oldValue = (string) e.OldValue;
            String newValue = (string) e.NewValue; 
 
            if (!String.Equals(oldValue, newValue))
            { 
                // If we get here the value has changed so we reload annotations
                AnnotationService service = AnnotationService.GetService(d);
                if (service != null && service.IsEnabled)
                { 
                    service.UnloadAnnotations(d);
                    service.LoadAnnotations(d); 
                } 
            }
        } 

        private static object CoerceDataId(DependencyObject d, object value)
        {
            string newValue = (string) value; 

            return (newValue != null && newValue.Length == 0) ? null : value; 
        } 

 
        /// 
        ///     Creates a DataId locator part for node.
        /// 
        /// logical tree node for which a locator part will be created 
        /// a DataId locator part for node, or null if node has no
        /// value for the DataIdProperty 
        /// node is null 
        private ContentLocatorPart CreateLocatorPart(DependencyObject node)
        { 
            Debug.Assert(node != null, "DependencyObject can not be null");

            // Get values from the node
            string nodeId = GetNodeId(node); 
            if ((nodeId == null) || (nodeId.Length == 0))
                return null; 
 
            ContentLocatorPart part = new ContentLocatorPart(DataIdElementName);
 
            part.NameValuePairs.Add(ValueAttributeName, nodeId);
            return part;
        }
 
        /// 
        ///     Get the value of the DataId dependency property for a 
        ///     DependencyObject. 
        /// 
        /// the object whose DataId value is to be retrieved 
        /// the object's DataId, if it is set, null otherwise
        internal String GetNodeId(DependencyObject d)
        {
            Debug.Assert(d != null, "DependencyObject can not be null"); 

            String id = d.GetValue(DataIdProperty) as string; 
 
            // Return null if the string is empty
            if (String.IsNullOrEmpty(id)) 
            {
                id = null;
            }
 
            return id;
        } 
 
        #endregion Private Methods
 
        //-----------------------------------------------------
        //
        //  Private Fields
        // 
        //------------------------------------------------------
 
        #region Private Fields 

        ///  
        ///     The type name of locator parts handled by this  handler.
        ///     This is internal and available to the processor that
        ///     is closely aligned with this handler.
        ///  
        private static readonly XmlQualifiedName DataIdElementName = new XmlQualifiedName("DataId", AnnotationXmlConstants.Namespaces.BaseSchemaNamespace);
 
        //the name of the value attribute 
        private const String ValueAttributeName = "Value";
 
        // ContentLocatorPart types understood by this processor
        private static readonly XmlQualifiedName[] LocatorPartTypeNames = 												
                new XmlQualifiedName[]
                { 
                    DataIdElementName
                }; 
 
        #endregion Private Fields
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
#pragma warning disable 1634, 1691 
//------------------------------------------------------------------------------
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved. 
// 
// 
// Description: 
//     DataIdProcessor walks the tree and loads annotations based on unique ids
//     identified by the DataIdProperty.  It loads annotations when it 
//     reaches a leaf in the tree or when it runs into a node with the
//     FetchAnnotationsAsBatch property set to true.
//     Spec: http://team/sites/ag/Specifications/Anchoring%20Namespace%20Spec.doc
// 
// History:
//  12/01/2002: magedz: Created - based on architectural discussions and design 
//                      by axelk, rruiz, magedz 
//  07/22/2003: rruiz:  Ported to WCP
//  08/18/2003: rruiz:  Updated to Anchoring Namespace Spec. 
//
//-----------------------------------------------------------------------------

using System; 
using System.Diagnostics;
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel;
using System.Windows; 
using System.Windows.Annotations;
using System.Windows.Annotations.Storage;
using System.Windows.Markup;
using System.Windows.Threading; 
using System.Xml;
 
using MS.Utility; 

namespace MS.Internal.Annotations.Anchoring 
{
    /// 
    ///     DataIdProcessor walks the tree and loads annotations based on unique ids
    ///     identified by the DataIdProperty.  It loads annotations when it 
    ///     reaches a leaf in the tree or when it runs into a node with the
    ///     FetchAnnotationsAsBatch property set to true. 
    ///  
    internal sealed class DataIdProcessor : SubTreeProcessor
    { 
        //-----------------------------------------------------
        //
        //  Constructors
        // 
        //-----------------------------------------------------
 
        #region Constructors 

        ///  
        ///     Creates an instance of DataIdProcessor.
        /// 
        /// the manager that owns this processor
        /// manager is null 
        public DataIdProcessor(LocatorManager manager) : base(manager)
        { 
        } 

        #endregion Constructors 

        //------------------------------------------------------
        //
        //  Public Methods 
        //
        //----------------------------------------------------- 
 
        #region Public Methods
 
        /// 
        ///     If and only if the current node has a DataId set and has FetchAnnotationsAsBatch
        ///     set to true, then all annotations for the subtree rooted at this node are loaded
        ///     at once. 
        /// 
        /// node to process 
        /// indicates the callback was called by 
        /// this processor
        ///  
        ///     a list of AttachedAnnotations loaded during the processing of
        ///     the node; can be null if no annotations were loaded
        /// 
        /// node is null 
        public override IList PreProcessNode(DependencyObject node, out bool calledProcessAnnotations)
        { 
            if (node == null) 
                throw new ArgumentNullException("node");
 
            // We get the local value so we can distinguish between the property
            // being set or not.  We don't want to rely on null or String.Empty because
            // those might have been the values set.
            object dataId = node.ReadLocalValue(DataIdProcessor.DataIdProperty); 
            bool fetchAsBatch = (bool) node.GetValue(FetchAnnotationsAsBatchProperty);
 
            // If the current node has an ID set on it and FetchAnnotationsAsBatch is 
            // set to true, we process this node immediately and return.  All its children
            // will be processed indirectly. 
            if (fetchAsBatch && dataId != DependencyProperty.UnsetValue)
            {
                calledProcessAnnotations = true;
                return Manager.ProcessAnnotations(node); 
            }
 
            calledProcessAnnotations = false; 
            return null;
        } 

        /// 
        ///     This method is called after PreProcessNode and after all the children
        ///     in the subtree have been processed (or skipped if PreProcessNode returns 
        ///     true for calledProcessAnnotations).
        ///     If no calls to ProcessAnnotations were made for any portion of the subtree below 
        ///     this node, then annotations for this node will be loaded 
        /// 
        /// the node to process 
        /// indicates whether calledProcessAnnotations
        /// was returned as true by any node underneath this node
        /// indicates whether ProcessAnnotations was called
        /// by this method 
        /// 
        ///     a list of AttachedAnnotations loaded during the processing of 
        ///     the node; can be null if no annotations were loaded 
        /// 
        public override IList PostProcessNode(DependencyObject node, bool childrenCalledProcessAnnotations, out bool calledProcessAnnotations) 
        {
            if (node == null)
                throw new ArgumentNullException("node");
 
            // We get the local value so we can distinguish between the property
            // being set or not.  We don't want to rely on null or String.Empty because 
            // those might have been the values set. 
            object dataId = node.ReadLocalValue(DataIdProcessor.DataIdProperty);
            bool fetchAsBatch = (bool) node.GetValue(FetchAnnotationsAsBatchProperty); 

            // If no children were processed, we try and process this node
            if (!fetchAsBatch && !childrenCalledProcessAnnotations && dataId != DependencyProperty.UnsetValue)
            { 
                FrameworkElement nodeParent = null;
                FrameworkElement feNode = node as FrameworkElement; 
                if (feNode != null) 
                {
                    nodeParent = feNode.Parent as FrameworkElement; 
                }
                AnnotationService service = AnnotationService.GetService(node);
                if (service != null &&
                    (service.Root == node || 
                    (nodeParent != null && service.Root == nodeParent.TemplatedParent)))
                { 
                    calledProcessAnnotations = true; 
                    return Manager.ProcessAnnotations(node);
                } 
            }

            calledProcessAnnotations = false;
            return null; 
        }
 
        ///  
        ///     Generates a locator part list identifying node.  If node has a
        ///     value for DataIdProperty, a locator with a single locator part 
        ///     containing the id value is returned.  Otherwise null is returned.
        /// 
        /// the node to generate a locator for
        /// specifies whether or not generating should 
        /// continue for the rest of the path; always set to true
        /// if node has a value for DataIdProperty, a locator with a 
        /// single locator part containing the id value; null otherwise 
        /// 
        /// node is null 
        public override ContentLocator GenerateLocator(PathNode node, out bool continueGenerating)
        {
            if (node == null)
                throw new ArgumentNullException("node"); 

            continueGenerating = true; 
 
            ContentLocator locator = null;
            ContentLocatorPart newLocatorPart = CreateLocatorPart(node.Node); 
            if (newLocatorPart != null)
            {
                locator = new ContentLocator();
                locator.Parts.Add(newLocatorPart); 
            }
 
            return locator; 
        }
 
        /// 
        ///     Searches the logical tree for a node matching the values of
        ///     locatorPart.  The search begins with startNode.
        ///  
        /// locator part to be matched, must be of the type
        /// handled by this processor 
        /// logical tree node to start search at 
        /// return flag indicating whether the search
        /// should continue (presumably because the search was not exhaustive) 
        /// returns a node that matches the locator part; null if no such
        /// node is found
        /// locatorPart or startNode are
        /// null 
        /// locatorPart is of the incorrect
        /// type 
        public override DependencyObject ResolveLocatorPart(ContentLocatorPart locatorPart, DependencyObject startNode, out bool continueResolving) 
        {
            if (locatorPart == null) 
                throw new ArgumentNullException("locatorPart");

            if (startNode == null)
                throw new ArgumentNullException("startNode"); 

            if (DataIdElementName != locatorPart.PartType) 
                throw new ArgumentException(SR.Get(SRID.IncorrectLocatorPartType, locatorPart.PartType.Namespace + ":" + locatorPart.PartType.Name), "locatorPart"); 

            // Initial value 
            continueResolving = true;

            // Get the values from the locator part...
            string id = locatorPart.NameValuePairs[ValueAttributeName]; 
            if(id == null)
            { 
                throw new ArgumentException(SR.Get(SRID.IncorrectLocatorPartType, locatorPart.PartType.Namespace + ":" + locatorPart.PartType.Name), "locatorPart"); 
            }
 
            // and from the node to examine.
            string nodeId = GetNodeId(startNode);

            if (nodeId != null) 
            {
                if (nodeId.Equals(id)) 
                { 
                    return startNode;
                } 
                else
                {
                    // If there was a value and it didn't match,
                    // we shouldn't bother checking the subtree 
                    continueResolving = false;
                } 
            } 

            return null; 
        }

        /// 
        ///     Returns a list of XmlQualifiedNames representing the 
        ///     the locator parts this processor can resolve/generate.
        ///  
        public override XmlQualifiedName[] GetLocatorPartTypes() 
        {
            return (XmlQualifiedName[])LocatorPartTypeNames.Clone(); 
        }

        #endregion Public Methods
 
        //------------------------------------------------------
        // 
        //  Public Operators 
        //
        //------------------------------------------------------ 

        //-----------------------------------------------------
        //
        //  Public Events 
        //
        //------------------------------------------------------ 
 
        //-----------------------------------------------------
        // 
        //  Public Properties
        //
        //-----------------------------------------------------
 
        #region Public Properties
 
        ///  
        ///     Id used to register this processor with the LocatorManager.  Registration
        ///     is done by the framework and does not need to be repeated.  Use this 
        ///     string in markup as the value for SubTreeProcessorIdProperty.
        /// 
        public const String Id = "Id";
 
        /// 
        ///     Used to specify a unique id for the data represented by a 
        ///     logical tree node.  Attach this property to the element with a 
        ///     unique value.
        ///  
#pragma warning suppress 7009
        public static readonly DependencyProperty DataIdProperty =
                DependencyProperty.RegisterAttached(
                        "DataId", 
                        typeof(String),
                        typeof(DataIdProcessor), 
                        new PropertyMetadata( 
                                (string) null,
                                new PropertyChangedCallback(OnDataIdPropertyChanged), 
                                new CoerceValueCallback(CoerceDataId)));

        /// 
        ///    Sets the value of the DataId attached property 
        ///    of the LocatorManager class.
        ///  
        /// element to which to write the attached property 
        /// the value to set
        /// d is null 
        public static void SetDataId(DependencyObject d, String id)
        {
            if(d == null)
                throw new ArgumentNullException("d"); 

            d.SetValue(DataIdProperty, id); 
        } 

        ///  
        ///    Gets the value of the DataId attached property
        ///    of the LocatorManager class.
        /// 
        /// the object from which to read the attached property 
        /// the value of the DataId attached property
        /// d is null 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public static String GetDataId(DependencyObject d)
        { 
            if (d == null)
                throw new ArgumentNullException("d");

            return d.GetValue(DataIdProperty) as String; 
        }
 
        ///  
        ///     Property that specifies, when set to true on an element, this
        ///     processor should load all annotations for the subtree rooted 
        ///     a the element as a batch.
        /// 
#pragma warning suppress 7009
        public static readonly DependencyProperty FetchAnnotationsAsBatchProperty = DependencyProperty.RegisterAttached( 
                "FetchAnnotationsAsBatch",
                typeof(bool), 
                typeof(DataIdProcessor), 
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
 
        /// 
        ///    Sets the value of the FetchAnnotationsAsBatch attached property
        ///    of the LocatorManager class.
        ///  
        /// element to which to write the attached property
        /// the value to set 
        /// d is null 
        public static void SetFetchAnnotationsAsBatch(DependencyObject d, bool id)
        { 
            if(d == null)
                throw new ArgumentNullException("d");

            d.SetValue(FetchAnnotationsAsBatchProperty, id); 
        }
 
 
        /// 
        ///    Gets the value of the FetchAnnotationsAsBatch attached property 
        ///    of the LocatorManager class.
        /// 
        /// the object from which to read the attached property
        /// the value of the FetchAnnotationsAsBatch attached property 
        /// d is null
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public static bool GetFetchAnnotationsAsBatch(DependencyObject d) 
        {
            if(d == null) 
                throw new ArgumentNullException("d");

            return (bool)d.GetValue(FetchAnnotationsAsBatchProperty);
        } 

        #endregion Public Properties 
 
        //-----------------------------------------------------
        // 
        //  Private Methods
        //
        //------------------------------------------------------
 
        #region Private Methods
 
        ///  
        ///    Callback triggered when a DataIdProperty value changes.
        ///    If the values are really different we unload and reload annotations 
        ///    using the new value.
        /// 
        private static void OnDataIdPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            String oldValue = (string) e.OldValue;
            String newValue = (string) e.NewValue; 
 
            if (!String.Equals(oldValue, newValue))
            { 
                // If we get here the value has changed so we reload annotations
                AnnotationService service = AnnotationService.GetService(d);
                if (service != null && service.IsEnabled)
                { 
                    service.UnloadAnnotations(d);
                    service.LoadAnnotations(d); 
                } 
            }
        } 

        private static object CoerceDataId(DependencyObject d, object value)
        {
            string newValue = (string) value; 

            return (newValue != null && newValue.Length == 0) ? null : value; 
        } 

 
        /// 
        ///     Creates a DataId locator part for node.
        /// 
        /// logical tree node for which a locator part will be created 
        /// a DataId locator part for node, or null if node has no
        /// value for the DataIdProperty 
        /// node is null 
        private ContentLocatorPart CreateLocatorPart(DependencyObject node)
        { 
            Debug.Assert(node != null, "DependencyObject can not be null");

            // Get values from the node
            string nodeId = GetNodeId(node); 
            if ((nodeId == null) || (nodeId.Length == 0))
                return null; 
 
            ContentLocatorPart part = new ContentLocatorPart(DataIdElementName);
 
            part.NameValuePairs.Add(ValueAttributeName, nodeId);
            return part;
        }
 
        /// 
        ///     Get the value of the DataId dependency property for a 
        ///     DependencyObject. 
        /// 
        /// the object whose DataId value is to be retrieved 
        /// the object's DataId, if it is set, null otherwise
        internal String GetNodeId(DependencyObject d)
        {
            Debug.Assert(d != null, "DependencyObject can not be null"); 

            String id = d.GetValue(DataIdProperty) as string; 
 
            // Return null if the string is empty
            if (String.IsNullOrEmpty(id)) 
            {
                id = null;
            }
 
            return id;
        } 
 
        #endregion Private Methods
 
        //-----------------------------------------------------
        //
        //  Private Fields
        // 
        //------------------------------------------------------
 
        #region Private Fields 

        ///  
        ///     The type name of locator parts handled by this  handler.
        ///     This is internal and available to the processor that
        ///     is closely aligned with this handler.
        ///  
        private static readonly XmlQualifiedName DataIdElementName = new XmlQualifiedName("DataId", AnnotationXmlConstants.Namespaces.BaseSchemaNamespace);
 
        //the name of the value attribute 
        private const String ValueAttributeName = "Value";
 
        // ContentLocatorPart types understood by this processor
        private static readonly XmlQualifiedName[] LocatorPartTypeNames = 												
                new XmlQualifiedName[]
                { 
                    DataIdElementName
                }; 
 
        #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