可视化命中测试

在可视化容器里通常需要DrawVisual对象画东西

如果需要知道是否选择了DrawVisual需要使用可视化树的命中测试

简单案例

cs 复制代码
如果点中了可视化对象
public DrawingVisual? GetVisual(Point point)
{
    HitTestResult result = VisualTreeHelper.HitTest(this, point);
    return result.VisualHit as DrawingVisual;
}

获取区域中的可视化对象

cs 复制代码
public List<DrawingVisual> GetVisuals(Geometry region)
{
    hits.Clear();

    HitTestResultCallback callback = new HitTestResultCallback(HitTestCallback);//回调
    GeometryHitTestParameters parameters = new GeometryHitTestParameters(region);
    
    //命中测试
    VisualTreeHelper.HitTest(this,null, callback, parameters);

    return hits;
}

/// <summary>
/// 回调方法。命中到的小方格添加到hits
/// </summary>
/// <param name="result">命中测试结果</param>
/// <returns></returns>
private HitTestResultBehavior HitTestCallback(HitTestResult result)
{
    GeometryHitTestResult geometryResult = (GeometryHitTestResult)result;
    DrawingVisual visual= result.VisualHit as DrawingVisual;
    if (visual != null && geometryResult.IntersectionDetail== IntersectionDetail.FullyInside)
    {
        hits.Add(visual);
        return HitTestResultBehavior.Stop;
    }
    return HitTestResultBehavior.Continue;
}

VisualTreeHelper.HitTest(this,null, callback, parameters);

这里主要讲筛选回调

cs 复制代码
//如果是Canvas跳过 
private HitTestFilterBehavior HitTestFilter(DependencyObject o)
        {
            Type type = o.GetType();
            switch (type.Name) {
                case "Canvas":
                    return HitTestFilterBehavior.ContinueSkipSelf;
                default:
                    return HitTestFilterBehavior.Continue;
            }
        }

重写默认命中测试

可以通过重写 HitTestCore 方法重写视觉对象的默认命中测试支持。 这意味着,在调用 HitTest 方法时,将调用 HitTestCore 的替代实现。 当命中测试落在视觉对象的边框内时,将调用重写的方法,即使坐标落在视觉对象呈现内容之外也是如此。

cs 复制代码
// Override default hit test support in visual object.
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
    // Perform actions based on hit test of bounding rectangle.
    // ...

    // Return results of base class hit testing,
    // which only returns hit on the geometry of visual objects.
    return base.HitTestCore(hitTestParameters);//使用默认的
    //return new PointHitTestResult(this, pt);
}

例子 自定义return new PointHitTestResult(this, pt);
public class MyCircleButton : Button
{
    protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
    {
        // 1. 获取命中点(相对当前控件)
        Point pt = hitTestParameters.HitPoint;
        // 2. 自定义命中判断:是否在圆形区域内(控件中心为圆心,半径为控件最小边长的一半)
        Point center = new Point(this.ActualWidth / 2, this.ActualHeight / 2);
        double radius = Math.Min(this.ActualWidth, this.ActualHeight) / 2;
        double distance = Math.Sqrt(Math.Pow(pt.X - center.X, 2) + Math.Pow(pt.Y - center.Y, 2));

        // 3. 满足自定义条件,强制返回命中结果;否则沿用默认逻辑(或返回null)
        if (distance <= radius)
        {
            // 强制指定当前圆形按钮为命中目标
            return new PointHitTestResult(this, pt);
        }
        else
        {
            // 不满足条件时,沿用默认逻辑(或返回null表示未命中)
            return base.HitTestCore(hitTestParameters);
        }
    }
}
相关推荐
l1m0_11 分钟前
智能电动自行车管理后台实战:AI生成页面与React组件化技巧
前端·react.js·ui·ai·设计
库玛西13 分钟前
深入浅出Linux select网络模型:从底层位图原理到C++面向对象高级封装
linux·服务器·网络·c++·ubuntu
Tingjct15 分钟前
线程详细讲解---聚焦linux
linux·服务器·jvm
Patrick_Wilson27 分钟前
为什么gitlab的MR会默认有一个merge commit
前端·git·gitlab
ComputerInBook30 分钟前
linux包管理工具——yum(YellowdogUpdaterModified)
linux·运维·服务器·yum·dnf
霸道流氓气质32 分钟前
Spring AI 多模态开发指南:图片理解与语音合成
java·人工智能·spring
en.en..36 分钟前
Linux mmap 内存映射深度解析:基于帧缓冲 /dev/fb0
java·服务器·前端
洋不写bug39 分钟前
链表补充练习,双链表的模拟实现
java·数据结构·链表·双链表·底层实现
后台模板学习42 分钟前
用 IM 即时聊天项目一次讲清消息去重算法的踩坑与解决方案
java·数据库·spring
秋名RG44 分钟前
2026/6/15 系统故障复盘与整改方案
java·架构