欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF使用VisualTreeHelper进行复杂命中测试

程序员文章站 2022-10-27 19:32:06
WPF使用VisualTreeHelper进行复杂命中测试 一、简介 接上篇的简单命中测试,添加VisualTreeHelper复杂命中测试。 二、代码案例 我在一个画板上在不同的位置放了3个圆形。给他们放置了不同的位置和填充不同的颜色,我们通过命中测试判断如果鼠标在圆上抬起了,我们读取当前圆的填充 ......

wpf使用visualtreehelper进行复杂命中测试

一、简介

接上篇的简单命中测试,添加visualtreehelper复杂命中测试。

二、代码案例

我在一个画板上在不同的位置放了3个圆形。给他们放置了不同的位置和填充不同的颜色,我们通过命中测试判断如果鼠标在圆上抬起了,我们读取当前圆的填充颜色。 

xaml:

<grid  mouseleftbuttonup="grid_mouseleftbuttonup"   mouserightbuttonup="grid_mouserightbuttonup">
        <canvas>
            <ellipse canvas.left="30" canvas.top="200"  width="130" height="130" fill="blue"/>
            <ellipse  opacity="0.6" canvas.left="70" canvas.top="50"  width="130" height="130" fill="violet"/>
            <ellipse  opacity="0.6"   canvas.left="150" canvas.top="50"  width="130" height="130" fill="orange"/>
            <ellipse  opacity="0.6"  canvas.left="110" canvas.top="0"  width="130" height="130" fill="red"/>
            <ellipse  canvas.left="220" canvas.top="100"  width="130" height="130" fill="yellow"/>
            <textblock  canvas.left="0" canvas.top="0" text="抬起鼠标左右键,开始对鼠标所在点进行命中测试" />
        </canvas>
    </grid>

后台逻辑:

 #region 左键简单命中测试
        private void grid_mouseleftbuttonup(object sender, mousebuttoneventargs e)
        {
            //最上层颜色
            var ellipse = getvisual(e.getposition(this));
            messagebox.show(ellipse?.fill?.tostring());
        }
        private ellipse getvisual(point point)
        {
            hittestresult hitresult = visualtreehelper.hittest(this, point);
            var ellipse = hitresult.visualhit as ellipse;
            return ellipse;
        }
        #endregion

        #region 右键复杂命中测试 
        private void grid_mouserightbuttonup(object sender, mousebuttoneventargs e)
        {
            point pt = e.getposition((uielement)sender);
            //我们定义一个10*10大小的几何
            ellipsegeometry expandedhittestarea = new ellipsegeometry(pt, 10.0, 10.0);
            var ellipses = getvisual(expandedhittestarea);
            stringbuilder stringbuilder = new stringbuilder();
            foreach (var item in ellipses)
            {
                //右击弹出所有层叠的颜色
                stringbuilder.append(item.fill.tostring() + ",");
            }
            messagebox.show(stringbuilder.tostring());
        }

        private hittestresultbehavior hittestcallback(hittestresult result)
        {
            geometryhittestresult geometryresult = (geometryhittestresult)result;
            ellipse visual = result.visualhit as ellipse;
            if (visual != null)
            {
                hits.add(visual);
            }
            return hittestresultbehavior.continue;
        }
        list<ellipse> hits = new list<ellipse>();
        private list<ellipse> getvisual(geometry region)
        {
            hits.clear();
            geometryhittestparameters parameters = new geometryhittestparameters(region);
            hittestresultcallback callback = new hittestresultcallback(this.hittestcallback);
            //第一个参数是我们要在什么容器内查找(我们现在是在整个window)。
            //第二个参数是筛选回调值的方法,我们目前不需要。
            //第三个参数是命中测试回调结果。
            //第四个参数是需要检测的区域。
            visualtreehelper.hittest(this, null, callback, parameters);
            return hits;
        }
        #endregion

三、运行效果

如下图右键点击小星星处,弹出三种html颜色:

WPF使用VisualTreeHelper进行复杂命中测试

如下图左键点击小星星处,仅弹出一种html颜色:

WPF使用VisualTreeHelper进行复杂命中测试