// Token: 0x06007C09 RID: 31753 RVA: 0x0022DEA4 File Offset: 0x0022C0A4 internal IList <IAttachedAnnotation> ProcessSubTree(DependencyObject subTree) { if (subTree == null) { throw new ArgumentNullException("subTree"); } LocatorManager.ProcessingTreeState processingTreeState = new LocatorManager.ProcessingTreeState(); PrePostDescendentsWalker <LocatorManager.ProcessingTreeState> prePostDescendentsWalker = new PrePostDescendentsWalker <LocatorManager.ProcessingTreeState>(TreeWalkPriority.VisualTree, new VisitedCallback <LocatorManager.ProcessingTreeState>(this.PreVisit), new VisitedCallback <LocatorManager.ProcessingTreeState>(this.PostVisit), processingTreeState); prePostDescendentsWalker.StartWalk(subTree); return(processingTreeState.AttachedAnnotations); }
// Token: 0x06007C11 RID: 31761 RVA: 0x0022E4B0 File Offset: 0x0022C6B0 private LocatorManager.ResolvingLocatorState ResolveSingleLocator(ref object selection, ref AttachmentLevel attachmentLevel, AttachmentLevel attemptedLevel, ContentLocator locator, int offset, DependencyObject startNode, bool skipStartNode) { LocatorManager.ResolvingLocatorState resolvingLocatorState = new LocatorManager.ResolvingLocatorState(); resolvingLocatorState.LocatorPartIndex = offset; resolvingLocatorState.ContentLocatorBase = locator; PrePostDescendentsWalker <LocatorManager.ResolvingLocatorState> prePostDescendentsWalker = new PrePostDescendentsWalker <LocatorManager.ResolvingLocatorState>(TreeWalkPriority.VisualTree, new VisitedCallback <LocatorManager.ResolvingLocatorState>(this.ResolveLocatorPart), new VisitedCallback <LocatorManager.ResolvingLocatorState>(this.TerminateResolve), resolvingLocatorState); prePostDescendentsWalker.StartWalk(startNode, skipStartNode); if (resolvingLocatorState.AttachmentLevel == AttachmentLevel.Full && resolvingLocatorState.AttachedAnchor != null) { if (selection != null) { SelectionProcessor selectionProcessor = this.GetSelectionProcessor(selection.GetType()); if (selectionProcessor != null) { object obj; if (selectionProcessor.MergeSelections(selection, resolvingLocatorState.AttachedAnchor, out obj)) { selection = obj; } else { attachmentLevel &= ~attemptedLevel; } } else { attachmentLevel &= ~attemptedLevel; } } else { selection = resolvingLocatorState.AttachedAnchor; } } else { attachmentLevel &= ~attemptedLevel; } return(resolvingLocatorState); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods /// <summary> /// Traverse the element tree starting at subtree and load /// annotations for that subtree. /// </summary> /// <param name="subTree">root of the subtree for which to load annotations</param> /// <returns>list of IAttachedAnnotations that were loaded for 'node'; /// the list will never be null but may be empty</returns> /// <exception cref="ArgumentNullException">subtree is null</exception> internal IList<IAttachedAnnotation> ProcessSubTree(DependencyObject subTree) { if (subTree == null) throw new ArgumentNullException("subTree"); ProcessingTreeState data = new ProcessingTreeState(); PrePostDescendentsWalker<ProcessingTreeState> walker = new PrePostDescendentsWalker<ProcessingTreeState>(TreeWalkPriority.VisualTree, PreVisit, PostVisit, data); walker.StartWalk(subTree); return data.AttachedAnnotations; }
/// <summary> /// Resolves a single locator starting at the given startNode. /// Sets the selection and attachmentLevel if necessary. /// </summary> /// <param name="selection">object representing the content that has been resolved /// so far; updated if the locator passed in is resolved</param> /// <param name="attachmentLevel">attachmentLevel of content that has been resolved /// so far; updated based on the resolution of the passed in locator</param> /// <param name="attemptedLevel">the level that is represented by this locator - /// start, middle or end</param> /// <param name="locator">the locator to resolve</param> /// <param name="offset">the offset into the locator to start the resolution at</param> /// <param name="startNode">the node to start the resolution at</param> /// <param name="skipStartNode">whether or not the start node should be looked at</param> /// <returns>the data representing the resolution of the single locator; used for /// special cases by calling code to override results from this method</returns> private ResolvingLocatorState ResolveSingleLocator(ref object selection, ref AttachmentLevel attachmentLevel, AttachmentLevel attemptedLevel, ContentLocator locator, int offset, DependencyObject startNode, bool skipStartNode) { ResolvingLocatorState data = new ResolvingLocatorState(); data.LocatorPartIndex = offset; data.ContentLocatorBase = locator; PrePostDescendentsWalker<ResolvingLocatorState> walker = new PrePostDescendentsWalker<ResolvingLocatorState>(TreeWalkPriority.VisualTree, ResolveLocatorPart, TerminateResolve, data); walker.StartWalk(startNode, skipStartNode); if (data.AttachmentLevel == AttachmentLevel.Full && data.AttachedAnchor != null) { // Merge the results with pre-existing selection if (selection != null) { SelectionProcessor selProcessor = GetSelectionProcessor(selection.GetType()); object newSelection; if (selProcessor != null) { if (selProcessor.MergeSelections(selection, data.AttachedAnchor, out newSelection)) { selection = newSelection; } else { // If we can't merge, them this locator isn't included in final results so we // we turn off the level that we are attempting to resolve attachmentLevel &= ~attemptedLevel; } } else { // If not selection processor, the locator can't be resolved so // we turn off the level that we were attempting to resolve attachmentLevel &= ~attemptedLevel; } } else { selection = data.AttachedAnchor; } } else { // ContentLocator didn't fully resolve so we turn off the level // that we were attempting to resolve attachmentLevel &= ~attemptedLevel; } return data; }
/// <summary> /// Invalidate inheritable properties and resource /// references during a tree change operation. /// </summary> internal static void InvalidateOnTreeChange( FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, bool isAddOperation) { Debug.Assert(fe != null || fce != null, "Node with the tree change notification must be an FE or an FCE."); Debug.Assert(parent != null, "Must have a parent that the current node is connected to or disconnected from."); // If the tree change is for a non-FE/FCE parent then we need to find // the nearest FE/FCE parent inorder to propagate inheritance correctly. FrameworkObject parentFO = new FrameworkObject(parent); if (!parentFO.IsValid) { parent = parentFO.FrameworkParent.DO; } // We're interested in changes to the Template property that occur during // the walk - if the template has changed we don't need to invalidate // template-driven properties a second time. The HasTemplateChanged property // is cleared on the first visit to each node, so that it means "template // changed during the walk". But one relevant node isn't visited during // the walk - the templated parent of the initial node. So we handle that now. FrameworkObject fo = new FrameworkObject(fe, fce); // Synchronize the ShouldLookupImplicitStyles flag with respect to the parent here // because for the root node of a tree change UpdateStyleProperty happens right here // in this method. And we need to have synchrnozed the ShouldLookupImplicitStyles // before we re-query the Style property. if (isAddOperation) { fo.SetShouldLookupImplicitStyles(); } fo.Reset(fo.TemplatedParent); fo.HasTemplateChanged = false; DependencyObject d = (fe != null) ? (DependencyObject)fe : (DependencyObject)fce; // during a tree walk to invalidate inherited properties, we typically // call UpdateStyle from FE/FCE.InvalidateTreeDependentProperties. But // for the root element of the tree change, we need to record old values // for inherited properties before we've updated the inheritance parent; // so do the updatestyle here before we record old values so that we // capture any updates provided by styles. if (fe != null) { if (fe.IsInitialized && !fe.HasLocalStyle) { // Clear the HasStyleChanged flag fe.HasStyleChanged = false; fe.HasStyleInvalidated = false; fe.HasTemplateChanged = false; fe.AncestorChangeInProgress = true; fe.UpdateStyleProperty(); fe.AncestorChangeInProgress = false; } } else { if (!fce.HasLocalStyle) { // Clear the HasStyleChanged flag fce.HasStyleChanged = false; fce.HasStyleInvalidated = false; fce.AncestorChangeInProgress = true; fce.UpdateStyleProperty(); fce.AncestorChangeInProgress = false; } } if (HasChildren(fe, fce)) { // Spin up a DescendentsWalker only when // the current node has children to walk // If there is another tree walk that has already visited the // current node then we do not need to re-walk its sub-tree. FrameworkContextData fcdata = FrameworkContextData.From(d.Dispatcher); if (!fcdata.WasNodeVisited(d, TreeChangeDelegate)) { // The TreeChangeInfo object is used here to track // information that we have because we're doing a tree walk. TreeChangeInfo parentInfo = new TreeChangeInfo(d, parent, isAddOperation); // PrePostDescendentsWalker is used instead of the standard // DescendentsWalker because we need a "post" callback to know when // to pop the parent's InheritableProperties cache from the stack. PrePostDescendentsWalker<TreeChangeInfo> walker = new PrePostDescendentsWalker<TreeChangeInfo>( TreeWalkPriority.LogicalTree, TreeChangeDelegate, TreeChangePostDelegate, parentInfo); fcdata.AddWalker(TreeChangeDelegate, walker); try { walker.StartWalk(d); } finally { fcdata.RemoveWalker(TreeChangeDelegate, walker); } } } else { // Degenerate case when the current node is a leaf node and has no children. TreeChangeInfo parentInfo = new TreeChangeInfo(d, parent, isAddOperation); // Degenerate case of OnAncestorChanged for a single node OnAncestorChanged(fe, fce, parentInfo); // Degenerate case of OnPostAncestorChanged for a single node OnPostAncestorChanged(d, parentInfo); } }
// Token: 0x06000C61 RID: 3169 RVA: 0x0002E1F8 File Offset: 0x0002C3F8 internal static void InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, bool isAddOperation) { FrameworkObject frameworkObject = new FrameworkObject(parent); if (!frameworkObject.IsValid) { parent = frameworkObject.FrameworkParent.DO; } FrameworkObject frameworkObject2 = new FrameworkObject(fe, fce); if (isAddOperation) { frameworkObject2.SetShouldLookupImplicitStyles(); } frameworkObject2.Reset(frameworkObject2.TemplatedParent); frameworkObject2.HasTemplateChanged = false; DependencyObject dependencyObject = (fe != null) ? fe : fce; if (fe != null) { if (fe.IsInitialized && !fe.HasLocalStyle) { fe.HasStyleChanged = false; fe.HasStyleInvalidated = false; fe.HasTemplateChanged = false; fe.AncestorChangeInProgress = true; fe.UpdateStyleProperty(); fe.AncestorChangeInProgress = false; } } else if (!fce.HasLocalStyle) { fce.HasStyleChanged = false; fce.HasStyleInvalidated = false; fce.AncestorChangeInProgress = true; fce.UpdateStyleProperty(); fce.AncestorChangeInProgress = false; } if (TreeWalkHelper.HasChildren(fe, fce)) { FrameworkContextData frameworkContextData = FrameworkContextData.From(dependencyObject.Dispatcher); if (frameworkContextData.WasNodeVisited(dependencyObject, TreeWalkHelper.TreeChangeDelegate)) { return; } TreeChangeInfo data = new TreeChangeInfo(dependencyObject, parent, isAddOperation); PrePostDescendentsWalker <TreeChangeInfo> prePostDescendentsWalker = new PrePostDescendentsWalker <TreeChangeInfo>(TreeWalkPriority.LogicalTree, TreeWalkHelper.TreeChangeDelegate, TreeWalkHelper.TreeChangePostDelegate, data); frameworkContextData.AddWalker(TreeWalkHelper.TreeChangeDelegate, prePostDescendentsWalker); try { prePostDescendentsWalker.StartWalk(dependencyObject); return; } finally { frameworkContextData.RemoveWalker(TreeWalkHelper.TreeChangeDelegate, prePostDescendentsWalker); } } TreeChangeInfo info = new TreeChangeInfo(dependencyObject, parent, isAddOperation); TreeWalkHelper.OnAncestorChanged(fe, fce, info); bool visitedViaVisualTree = false; TreeWalkHelper.OnPostAncestorChanged(dependencyObject, info, visitedViaVisualTree); }