//在本例中,通过单独定义的HitTestResultCallback()方法实现回调函数。 //HitTestResultCallback()和GetVisuals()方法都使用命中集合,所以命中集合作为成员字段进行定义。然而,可以通过为回调函数使用匿名方法来避免这一点, //匿名方法可在GetVisuals()方法内声明 private HitTestResultBehavior HitTestCallback(HitTestResult result) { //回调方法实现了命中测试行为。通常HitTestResult对象只提供一个属性(VisualHit),但可以根据执行命中测试的类型,将他转换成两个派生类型中的任意 //一个。 //如果使用一个点进行命中测试,可将HitTestResult对象转换为PointHitTestResult对象,该类提供了一个不起眼的PointHint属性,该属性返回用于执行 //命中测试的原始点 //如果使用Geometry对象进行命中测试,可将HitTestResult对象转换为GeometryHitTestResult对象,并访问IntersectionDetail属性。IntersectionDetail //属性告知您几何图形是否完全封装了可视化对象(FullyInside),几何图形是否与可视化元素只是相互重叠(Intersets),或者用于命中测试的几何图形是否落 //在可视化元素的内部(FullyContains) //在本例中,只有当可视化对象完全位于命中测试区域时,才会对命中数量计数。 GeometryHitTestResult geometryResult = (GeometryHitTestResult)result; DrawingVisual visual = result.VisualHit as DrawingVisual; if (visual != null && geometryResult.IntersectionDetail == IntersectionDetail.FullyInside) { hits.Add(visual); } //最后,在回调函数的末尾,可返回两个HitTestResultBehavior枚举值中的一个: //返回Continue表示继续查找命中,返回Stop则表示结束查找过程 return(HitTestResultBehavior.Continue); }
private void GridA_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (e.LeftButton == MouseButtonState.Released) { hits.Clear(); mouseSelectionCounter = 0; GridA.Children.Remove(pth1); selectBox = new RectangleGeometry(); recTemp = new Rect(); pth1 = new Path(); //HitTestResult result = VisualTreeHelper.HitTest(GridA, e.GetPosition(this)); //Debug.WriteLine((result.VisualHit as Path).Name); GeometryHitTestParameters parameters = new GeometryHitTestParameters(recHitResult); HitTestResultCallback callback = new HitTestResultCallback((HitTestResult result) => { GeometryHitTestResult geometryResult = (GeometryHitTestResult)result; Path visual = result.VisualHit as Path; if (visual != null && geometryResult.IntersectionDetail == IntersectionDetail.FullyInside) { hits.Add(visual); } return(HitTestResultBehavior.Continue); }); VisualTreeHelper.HitTest(this, null, callback, parameters); foreach (Path x in hits) { Debug.WriteLine(x.Name); } } }
private HitTestResultBehavior HitTestCallback(HitTestResult result) { GeometryHitTestResult geometryResult = (GeometryHitTestResult)result; if (result.VisualHit is DrawingVisual visual && geometryResult.IntersectionDetail == IntersectionDetail.FullyInside) { myHits.Add(visual); } return(HitTestResultBehavior.Continue); }
private HitTestResultBehavior HitTestResultCallback(HitTestResult result) { GeometryHitTestResult testResult = (GeometryHitTestResult)result; DrawingVisual visual = result.VisualHit as DrawingVisual; if (visual != null && testResult.IntersectionDetail == IntersectionDetail.FullyInside) { hits.Add(visual); } return(HitTestResultBehavior.Continue); }
/// <summary> /// Represents a callback that is used to customize hit testing. /// WPF invokes HitRestResult to report hit test intersections to the user. /// </summary> /// <param name="result">The HitTestResult value that represents a visual object that is returned from a hit test.</param> /// <returns>A HitTestResultBehavior that represents the action resulting from the hit test.</returns> private HitTestResultBehavior HitTestCallback(HitTestResult result) { GeometryHitTestResult geometryResult = (GeometryHitTestResult)result; DrawingVisual visual = result.VisualHit as DrawingVisual; // Only include matches that are DrawingVisual objects and that are completely inside the geometry. if ((visual != null) && (geometryResult.IntersectionDetail == IntersectionDetail.FullyInside)) { hits.Add(visual); } return(HitTestResultBehavior.Continue); }
private HitTestResultBehavior hitTestResultCallback(HitTestResult result) { GeometryHitTestResult geometryHitTest = (GeometryHitTestResult)result; Rectangle visual = result.VisualHit as Rectangle; if (visual != null && geometryHitTest.IntersectionDetail == IntersectionDetail.FullyInside) { hitResultList.Add(visual); } return(HitTestResultBehavior.Continue); }
/// <summary> /// Returns a collection of Elements of type targetType that are located in the area of the Geometry geo in the subtree of the UIElement reference /// </summary> /// <param name="geo">the geometry which will be tested</param> /// <param name="reference">specifies the subtree that will be tested</param> /// <param name="targetType">specifies the type of elements that will be returned (subclasses of this type will also be returned)</param> /// <returns>A collection of Elements that are found by hittesting with the given parameters</returns> public static IEnumerable <DependencyObject> GetElementsInGeometry(Geometry geo, Visual reference, Type targetType) { List <DependencyObject> results = new List <DependencyObject>(); HitTestFilterCallback filter = (o) => { Type matchType = o.GetType(); //if we find an element of correct type, we can ignore its subtree //if we find an element of incorrect type, we can ignore it, but must check its children if (matchType == targetType || matchType.IsSubclassOf(targetType)) { return(HitTestFilterBehavior.ContinueSkipChildren); } else { return(HitTestFilterBehavior.ContinueSkipSelf); } }; HitTestResultCallback result = (r) => { GeometryHitTestResult ghr = r as GeometryHitTestResult; if (ghr.IntersectionDetail == IntersectionDetail.Empty) { return(HitTestResultBehavior.Continue); } Type matchType = r.VisualHit.GetType(); //again we check the type of the element, just to be sure that only correct types go into our collection if (matchType == targetType || matchType.IsSubclassOf(targetType)) { results.Add(r.VisualHit); } return(HitTestResultBehavior.Continue); }; VisualTreeHelper.HitTest(reference, filter, result, new GeometryHitTestParameters(geo)); return(results); }
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); }