点击测试行为 [英] Hit Test behavior

查看:150
本文介绍了点击测试行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code

 公共部分类主窗口:窗口
{
    公共主窗口(){
        的InitializeComponent();
    }

    名单<的UIElement> UCS =新的名单,其中,UIElement的>();

    私人无效Window_ previewMouseLeftButtonDown(对象发件人,
        MouseButtonEventArgs五)
    {
        ucs.Clear();

        点p = e.GetPosition((UIElement的)发送者);

        VisualTreeHelper.HitTest(本,空,
            新HitTestResultCallback(MyHitTestCallback)
            新PointHitTestParameters(对));

        Console.WriteLine(ucs.Count = {0},ucs.Count);

        的foreach(UCS的VAR项)
        {
            Console.WriteLine(项:{0},item.ToString());
        }
    }

    HitTestResultBehavior MyHitTestCallback(HitTestResult结果)
    {
        ucs.Add(result.VisualHit为UIElement的);
        返回HitTestResultBehavior.Continue;
    }
}
 

这是我的窗口

 <窗​​口>
    <电网>
        <我:的UserControl1的Horizo​​ntalAlignment =左保证金=82,88,0,0X:名称=userControl11VerticalAlignment =热门/>
        <我:的UserControl1的Horizo​​ntalAlignment =左保证金=168,166,0,0X:名称=userControl12VerticalAlignment =热门/>
        <我:的UserControl1的Horizo​​ntalAlignment =左保证金=231,130,0,0X:名称=userControl13VerticalAlignment =热门/>
    < /网格>
< /窗>
 

这是我的UC

 <用户控件>
    <电网>
        <标签内容=标签高度=44的Horizo​​ntalAlignment =左NAME =label1的VerticalAlignment =热门字号=20粗细=大胆WIDTH =78背景=#FF4B9FC4BorderBrush =#FF020A0D了borderThickness =1/>
    < /网格>
< /用户控件>
 

这是输出,当我点击一个用户控件,然后在2用户控件一个十字路口:

  ucs.Count = 2
项目:System.Windows.Controls.Border
项目:System.Windows.Controls.Border
ucs.Count = 3
项目:System.Windows.Controls.Border
项目:System.Windows.Controls.Border
项目:System.Windows.Controls.Border
 

为什么呢?在哪里鼠标实例下的用户控件?

PS:
现在,当我对标签上的了borderThickness = 0

  ucs.Count = 3
项目:System.Windows.Controls.TextBlock
项目:System.Windows.Controls.Border
项目:System.Windows.Controls.Border
ucs.Count = 3
项目:System.Windows.Controls.TextBlock
项目:System.Windows.Controls.Border
项目:System.Windows.Controls.Border
 

解决方案

的UserControl1 是看不见的。它的内容的是可见的,但你的的UserControl1 实例本身并没有任何自己的视觉效果。 (它永远不会。用户控件的工作实际上只是包含其他的东西。)

点击测试仅报告的元素,使得以可视化树的直接贡献。并且由于命中测试认为在隔离的每个元素中,这意味着被纯粹作为容器元件显示不出来。 (和相关的事实是,点击测试仅考虑实际上得到画的像素。所以,如果你有一个边框在这里你设置了 BorderBrush 和非零了borderThickness ,但你有没有背景,点击测试将只考虑边界轮廓是一个打击 - 边界内积分将不被视为打边界,因为它不是画在其内部东西

如果你需要做的命中测试这件事情,或者什么这个东西里面的风格,那么无论任何

  1. 使用鼠标进入/离开事件 - 那些泡沫,所以他们会得到甚至看不见的容器元素提出
  2. 使用 IsMouseOver
  3. 使用您使用,传递用户的控制作为第一个参数的命中测试功能,并治疗任何的打击作为一个指示命中测试点是用户控件中

第三个是比较复杂的,但如果你需要打比鼠标下的指目前其他测试点,你需要使用它。

I have the following code

public partial class MainWindow : Window
{
    public MainWindow() {
        InitializeComponent();
    }

    List<UIElement> ucs = new List<UIElement>();

    private void Window_PreviewMouseLeftButtonDown(object sender,
        MouseButtonEventArgs e)
    {
        ucs.Clear();

        Point p = e.GetPosition((UIElement)sender);

        VisualTreeHelper.HitTest(this, null,
            new HitTestResultCallback(MyHitTestCallback),
            new PointHitTestParameters(p));

        Console.WriteLine("ucs.Count = {0}", ucs.Count);

        foreach (var item in ucs)
        {
            Console.WriteLine("item: {0}", item.ToString());
        }
    }

    HitTestResultBehavior MyHitTestCallback(HitTestResult result)
    {
        ucs.Add(result.VisualHit as UIElement);
        return HitTestResultBehavior.Continue;
    }
}

this is my window

<Window>
    <Grid>
        <my:UserControl1 HorizontalAlignment="Left" Margin="82,88,0,0" x:Name="userControl11" VerticalAlignment="Top" />
        <my:UserControl1 HorizontalAlignment="Left" Margin="168,166,0,0" x:Name="userControl12" VerticalAlignment="Top" />
        <my:UserControl1 HorizontalAlignment="Left" Margin="231,130,0,0" x:Name="userControl13" VerticalAlignment="Top" />
    </Grid>
</Window>

this is my UC

<UserControl>
    <Grid>
        <Label Content="Label" Height="44" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="78" Background="#FF4B9FC4" BorderBrush="#FF020A0D" BorderThickness="1" />
    </Grid>
</UserControl>

this is the output when I click ON A USER CONTROL, then on a intersection of 2 UserControls:

ucs.Count = 2
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
ucs.Count = 3
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border

Why this? Where is the UserControl under the mouse instance?

PS:
Now, when I have on the Label the BorderThickness = 0

ucs.Count = 3
item: System.Windows.Controls.TextBlock
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
ucs.Count = 3
item: System.Windows.Controls.TextBlock
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border

解决方案

The UserControl1 is invisible. Its contents are visible, but your UserControl1 instance itself does not have any visuals of its own. (And it never will. A user control's job is really just to contain other things.)

Hit testing only reports elements that make a direct contribution to the visual tree. And since hit testing considers each element in isolation, this means that elements that are acting purely as containers don't show up. (And a related fact is that hit testing only considers the pixels that actually got painted. So if you have a Border where you've set the BorderBrush and a non-zero BorderThickness but you have no Background, the hit test will only consider the border outline to be a hit - points inside of the border will not be considered to hit the border because it's not painting anything in its interior.

If you need to do hit testing of a "this thing, or anything inside this thing" style, then either either

  1. use mouse enter/leave events - those bubble, and so they will get raised even on invisible container elements
  2. use IsMouseOver or
  3. use the hit test function you're using, passing the user control as the first argument, and treat any hit as an indication that the hit test point is inside the user control

The third one is more complex, but if you need to hit test points other than the one currently under the mouse, you'd need to use it.

这篇关于点击测试行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆