| File: System\Windows\DescendentsWalkerBase.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Windows.Media; using MS.Utility; namespace System.Windows { /// <summary> /// This is a base class to the DescendentsWalker. It is factored out so that /// FrameworkContextData can store and retrieve it from context local storage /// in a type agnostic manner. /// </summary> internal class DescendentsWalkerBase { #region Construction protected DescendentsWalkerBase(TreeWalkPriority priority) { _startNode = null; _priority = priority; _recursionDepth = 0; _nodes = new FrugalStructList<DependencyObject>(); } #endregion Construction internal bool WasVisited(DependencyObject d) { DependencyObject ancestor = d; while ((ancestor != _startNode) && (ancestor != null)) { DependencyObject logicalParent; if (ancestor is FrameworkElement fe) { logicalParent = fe.Parent; // FrameworkElement DependencyObject dependencyObjectParent = VisualTreeHelper.GetParent(fe); if (dependencyObjectParent != null && logicalParent != null && dependencyObjectParent != logicalParent) { return _nodes.Contains(ancestor); } // Follow visual tree if not null otherwise we follow logical tree if (dependencyObjectParent != null) { ancestor = dependencyObjectParent; continue; } } else { // FrameworkContentElement FrameworkContentElement ancestorFCE = ancestor as FrameworkContentElement; logicalParent = ancestorFCE?.Parent; } ancestor = logicalParent; } return (ancestor != null); } internal DependencyObject _startNode; internal TreeWalkPriority _priority; internal FrugalStructList<DependencyObject> _nodes; internal int _recursionDepth; } /// <summary> /// Enum specifying whether visual tree needs /// to be travesed first or the logical tree /// </summary> internal enum TreeWalkPriority { /// <summary> /// Traverse Logical Tree first /// </summary> LogicalTree, /// <summary> /// Traverse Visual Tree first /// </summary> VisualTree } }