private static IEnumerable <DependencyObject> GetDescendantsInZOrder(DependencyObject root) { if (root != null) { int childCount = VisualTreeHelper.GetChildrenCount(root); if (childCount > 0) { for (int i = childCount - 1; i >= 0; --i) { DependencyObject child = VisualTreeHelper.GetChild(root, i); if (child != null) { foreach (DependencyObject dependencyObject in ModelHitTestHelper.GetDescendantsInZOrder(child)) { if (dependencyObject != null) { yield return(dependencyObject); } } yield return(child); } } } } }
public static HitTestResult HitTest(Visual root, HitTestFilterCallback filterCallback, HitTestResultCallback resultCallback, HitTestParameters hitTestParameters, HitTestFilterCallback modelCallback) { ModelHitTestHelper.HitTestFilterCallbackWrapper filterCallbackWrapper = new ModelHitTestHelper.HitTestFilterCallbackWrapper(filterCallback); ModelHitTestHelper.HitTestResultCallbackWrapper resultCallbackWrapper = new ModelHitTestHelper.HitTestResultCallbackWrapper(resultCallback, HitTestResultBehavior.Continue); VisualTreeHelper.HitTest(root, filterCallbackWrapper.FilterCallback, resultCallbackWrapper.ResultCallback, hitTestParameters); HitTestResult topMostHit = resultCallbackWrapper.TopMostHit; bool flag = filterCallback == null && resultCallback == null; VisualHitTestArgs args = new VisualHitTestArgs(root, root, hitTestParameters); PointHitTestParameters hitTestParameters1 = hitTestParameters as PointHitTestParameters; GeometryHitTestParameters hitTestParameters2 = hitTestParameters as GeometryHitTestParameters; foreach (DependencyObject dependencyObject in ModelHitTestHelper.GetDescendantsInZOrder((DependencyObject)root)) { if (dependencyObject != null) { if (filterCallback == null && topMostHit != null && dependencyObject == topMostHit.VisualHit) { resultCallbackWrapper.PlayResults(); return(resultCallbackWrapper.TopMostHit); } Visual visual = dependencyObject as Visual; HitTestProvider singletonProvider = ModelHitTestHelper.GetSingletonProvider(dependencyObject); if (singletonProvider != null && (modelCallback == null || modelCallback((DependencyObject)visual) != HitTestFilterBehavior.Continue)) { args.UpdateChild(dependencyObject); HitTestResult result = (HitTestResult)null; if (hitTestParameters1 != null && visual != null) { PointHitTestResult pointHitTestResult = singletonProvider.HitTestPoint(args); if (pointHitTestResult != null && pointHitTestResult.VisualHit != null) { result = (HitTestResult)pointHitTestResult; } } else if (hitTestParameters2 != null && visual != null) { GeometryHitTestResult geometryHitTestResult = singletonProvider.HitTestGeometry(args); if (geometryHitTestResult != null && geometryHitTestResult.IntersectionDetail != IntersectionDetail.Empty && geometryHitTestResult.IntersectionDetail != IntersectionDetail.NotCalculated) { result = (HitTestResult)geometryHitTestResult; } } if (result != null) { HitTestFilterBehavior testFilterBehavior = filterCallbackWrapper.FilterCallback(dependencyObject); switch (testFilterBehavior) { case HitTestFilterBehavior.Continue: case HitTestFilterBehavior.Stop: resultCallbackWrapper.InsertResult(result); break; } if (flag && testFilterBehavior != HitTestFilterBehavior.ContinueSkipSelf || testFilterBehavior == HitTestFilterBehavior.Stop) { resultCallbackWrapper.PlayResults(); return(result); } } } } } resultCallbackWrapper.PlayResults(); return(resultCallbackWrapper.TopMostHit); }
public static HitTestResult HitTest(Visual reference, Point point, HitTestFilterCallback filterCallback) { return(ModelHitTestHelper.HitTest(reference, filterCallback, (HitTestResultCallback)null, (HitTestParameters) new PointHitTestParameters(point), (HitTestFilterCallback)null)); }