可视化命中测试

在可视化容器里通常需要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);
        }
    }
}
相关推荐
饭九钦vlog24 分钟前
dns形式的floodddos命令
linux·运维·服务器
gaize121331 分钟前
服务器异常的处理方法
服务器
vx_bisheyuange34 分钟前
基于SpringBoot的青年公寓服务平台
前端·vue.js·spring boot·毕业设计
web前端12335 分钟前
前端如何开发一个MCP Server - 安全审计实战项目介绍
前端·mcp
Anthony_23139 分钟前
MySql常用SQL命令
服务器·数据库·sql·mysql·http·oracle·udp
愤怒的代码1 小时前
从开发调试到生产上线:全维度 Android 内存监控与分析体系构建
android·java·kotlin
Dr_哈哈1 小时前
Node.js fs 与 path 完全指南
前端
树码小子1 小时前
网络原理(13):TCP协议十大核心机制 -- 确认应答 & 超时重传
服务器·网络·tcp/ip
悟能不能悟1 小时前
java HttpServletRequest 设置header
java·开发语言
啊花是条龙1 小时前
《产品经理说“Tool 分组要一条会渐变的彩虹轴,还要能 zoom!”——我 3 步把它拆成 1024 个像素》
前端·javascript·echarts