Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / Annotations / Anchoring / DataIdProcessor.cs / 1305600 / 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 IListPreProcessNode(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 IListPostProcessNode(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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CommentEmitter.cs
- CommandDevice.cs
- ProfileGroupSettingsCollection.cs
- QueryAccessibilityHelpEvent.cs
- Literal.cs
- XomlCompilerHelpers.cs
- SessionPageStateSection.cs
- StyleXamlParser.cs
- StateMachineHelpers.cs
- AsyncResult.cs
- PtsHost.cs
- FileEnumerator.cs
- SiteMapNode.cs
- TextParentUndoUnit.cs
- XmlHelper.cs
- WindowsServiceCredential.cs
- NetworkInformationPermission.cs
- RtfToXamlReader.cs
- ToolStripContainer.cs
- DetailsViewRow.cs
- KoreanLunisolarCalendar.cs
- DataControlFieldCollection.cs
- NavigationProgressEventArgs.cs
- PageAsyncTask.cs
- Compiler.cs
- DataGridViewRowPrePaintEventArgs.cs
- TreeNodeBindingCollection.cs
- IsolatedStorageException.cs
- AccessedThroughPropertyAttribute.cs
- HostingPreferredMapPath.cs
- VirtualizedItemPattern.cs
- Application.cs
- BroadcastEventHelper.cs
- PrintDialog.cs
- SqlNode.cs
- DataGridBoundColumn.cs
- AudioFormatConverter.cs
- ToolStripRenderer.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- TextUtf8RawTextWriter.cs
- ClientRuntimeConfig.cs
- CLRBindingWorker.cs
- SrgsSubset.cs
- ErrorFormatterPage.cs
- MaterializeFromAtom.cs
- RelatedView.cs
- NetCodeGroup.cs
- SspiSafeHandles.cs
- EnumerableRowCollection.cs
- LogRestartAreaEnumerator.cs
- MetadataArtifactLoaderCompositeResource.cs
- UnsafeNativeMethods.cs
- JournalEntryStack.cs
- EventsTab.cs
- XmlIlGenerator.cs
- JavaScriptSerializer.cs
- TableLayoutCellPaintEventArgs.cs
- SoapReflectionImporter.cs
- Pkcs7Signer.cs
- StrongNameKeyPair.cs
- storepermission.cs
- Sql8ExpressionRewriter.cs
- DuplicateWaitObjectException.cs
- StylusPointProperties.cs
- DocumentPageTextView.cs
- ICspAsymmetricAlgorithm.cs
- DataGridViewTextBoxEditingControl.cs
- GenericIdentity.cs
- BitmapImage.cs
- EdmScalarPropertyAttribute.cs
- EnumConverter.cs
- WebControlToolBoxItem.cs
- DateTimeFormatInfoScanner.cs
- Vertex.cs
- SqlUtils.cs
- Currency.cs
- WinEventHandler.cs
- DesignerVerbCollection.cs
- CommandConverter.cs
- ControlValuePropertyAttribute.cs
- SqlCacheDependency.cs
- IndentTextWriter.cs
- HierarchicalDataTemplate.cs
- WeakReferenceEnumerator.cs
- ActivitySurrogate.cs
- FixedTextContainer.cs
- RubberbandSelector.cs
- StylusCaptureWithinProperty.cs
- WorkflowInstance.cs
- PeerPresenceInfo.cs
- PermissionAttributes.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- NonBatchDirectoryCompiler.cs
- CheckBoxList.cs
- ThumbButtonInfoCollection.cs
- HWStack.cs
- SafeLocalAllocation.cs
- HotCommands.cs
- ComponentTray.cs
- cookiecollection.cs