如果另一个对象具有mousecapture,如何为一个对象触发MouseEnter? [英] How to fire MouseEnter for one object if another object has mousecapture?

查看:120
本文介绍了如果另一个对象具有mousecapture,如何为一个对象触发MouseEnter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题,还有一个vb.net 2010和wpf4项目.我有一个标签,当单击该标签时,它会捕获鼠标(MyLabel.captureMouse),并在屏幕上跟随它,直到再次单击鼠标为止,此时释放对象和鼠标捕获.

I have a strange question and a vb.net 2010 and wpf4 project. I have a label that, when clicked, captures the mouse (MyLabel.captureMouse) and follows it around the screen until the mouse clicks again, at which point the object and the mousecapture is released.

但是,我仍然需要另一个对象的mouseenter功能.如何使这两件事协同工作?

However, I still need the functionality of mouseenter for another object. How do I get these two things to work together?

看来有两种解决方案,我发现了其中一种.但是,由于Rick的也应该工作(尽管由于我的截止日期未经测试),并且我讨厌在这里回答自己的问题,所以我接受了他的回答.

There are two solutions to this, it seems, one of which I discovered. However, since Rick's should work as well (though untested because of my deadline), and I hate answering my own questions on here, I accepted his answer.

在等待他对我遇到的问题发表评论的中间,我终于找到了自己的解决方案.因此,请务必同时阅读我的​​回答和里克的回答.

In the interim of waiting for him to comment back to a problem I had, I wound up discovering my own solution. Thus, be sure to read both my answer and Rick's.

推荐答案

如果另一个对象是您的一个对象,则当您使用合成事件捕获鼠标时,您的标签和另一个对象可以配合使用.例如,在您的鼠标移动处理程序中,您可以检查Mouse.DirectlyOver以查看它是否是另一个对象,如果是,请做一点记账,然后在另一个对象上用MouseEnterMouseLeave调用RaiseEvent .如果您有一堆这样的对象,那么您就需要做更多的簿记工作.

If the other object is one of your objects, then your label and the other object can cooperate while you have the mouse captured using synthetic events. For example, in your mouse move handler, you can check Mouse.DirectlyOver to see if it is the other object and if so, do a little bookkeeping and then call RaiseEvent with either MouseEnter or MouseLeave on the other object. If you have a bunch of these objects then you just have more bookkeeping to do.

以上是指Mouse.DirectlyOver,在捕获鼠标时它特别不起作用.为了使上述内容更加具体并解决该错误,这是一个完整的工作示例.

The above refers to Mouse.DirectlyOver which specifically does not work when the mouse is captured. To make the above more concrete and to fix that error, here is a complete working example.

以下是显示画布的标记,具有鼠标捕获处理功能的矩形和具有输入/离开处理功能的椭圆:

Here is the markup showing a canvas, a rectangle with mouse capture handling, and an ellipse with enter/leave handling:

<Grid>
    <Canvas>
        <Rectangle Canvas.Left="0" Canvas.Top="0"
                   Fill="Red" Width="100" Height="100"
                   MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
                   MouseMove="Rectangle_MouseMove"
                   MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"/>
        <Ellipse Canvas.Left="0" Canvas.Top="100"
                   Fill="Green" Width="100" Height="100"
                   MouseEnter="Ellipse_MouseEnter"
                   MouseLeave="Ellipse_MouseLeave">
            <Ellipse.RenderTransform>
                <ScaleTransform/>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Canvas>
</Grid>

以下是事件处理程序,它们演示了如何在捕获鼠标时生成综合的输入/离开事件(但仅针对椭圆):

and here are the event handlers that demonstrate how to generate synthetic enter/leave events (but only for the ellipse) while the mouse is captured:

    private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var capturer = sender as FrameworkElement;
        capturer.CaptureMouse();
    }

    bool over = false;
    UIElement element;

    private void Rectangle_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton != MouseButtonState.Pressed) return;
        var capturer = sender as FrameworkElement;
        var hit = VisualTreeHelper.HitTest(this, e.GetPosition(this));
        if (hit == null) return;
        var thisElement = hit.VisualHit as Ellipse;
        var nowOver = thisElement != null;
        if (nowOver) element = thisElement;
        var args = new MouseEventArgs(Mouse.PrimaryDevice, 0);
        if (!over && nowOver) { args.RoutedEvent = UIElement.MouseEnterEvent; element.RaiseEvent(args); }
        if (over && !nowOver) { args.RoutedEvent = UIElement.MouseLeaveEvent; element.RaiseEvent(args); }
        over = nowOver;
    }

    private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        var capturer = sender as FrameworkElement;
        capturer.ReleaseMouseCapture();
    }

    private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
    {
        Debug.WriteLine("MouseEnter");
    }

    private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
    {
        Debug.WriteLine("MouseLeave");
    }

如果在调试器下运行演示,则会发现无论是否捕获到鼠标,都会调用enter/leave处理程序.

If you run the demo under the debugger you'lll see that the enter/leave handlers are called whether the mouse is captured or not.

这篇关于如果另一个对象具有mousecapture,如何为一个对象触发MouseEnter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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