如果鼠标失去对象的焦点,为什么MouseMove事件不起作用?

时间:2012-10-22 13:33:33

标签: c# wpf event-handling mouse

我的程序中基本上有一个简单的问题,我只想确保正确。它应该在单击鼠标按钮时添加MouseEventHandler,然后随着鼠标移动圆圈,直到删除事件处理程序。我将代码简化为基础:

XAML:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid Name="grid1" Background="White" MouseLeftButtonUp="grid_MouseUp">
        <Ellipse Height="50" HorizontalAlignment="Left" Margin="12,12,0,0" Name="ellipse1" Stroke="{x:Null}" VerticalAlignment="Top" Width="50" Fill="Black" MouseLeftButtonDown="ellipse1_MouseDown" />
    </Grid>
</Window>

C#:

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

    private static Point _oldPoint = new Point(), _newPoint = new Point();

    private void ellipse1_MouseDown(object sender, MouseButtonEventArgs e)
    {
        _oldPoint = e.GetPosition(grid1);
        grid1.MouseMove += new MouseEventHandler(grid_MouseMove);
    }

    private void grid_MouseUp(object sender, MouseButtonEventArgs e)
    {
        grid1.MouseMove -= new MouseEventHandler(grid_MouseMove);
    }

    private void grid_MouseMove(object sender, MouseEventArgs e)
    {
        _newPoint = e.GetPosition(grid1);
        ellipse1.Margin = new Thickness(ellipse1.Margin.Left - _oldPoint.X + _newPoint.X, ellipse1.Margin.Top - _oldPoint.Y + _newPoint.Y, 0, 0);
        _oldPoint = _newPoint;
    }
}

现在一般来说这段代码工作得很好,我认为它非常整洁,因为在实际按下按钮之前它不会检查鼠标的移动。但是,我的问题如下:

我必须将MouseMove事件添加到网格而不是圆圈,因为一旦鼠标指针失去圆圈的焦点(通过快速移动鼠标),它就不会再触发MouseMove事件。但为什么会发生这种情况呢?在事件开始时,鼠标肯定在圆圈上方然后移动。是的,它离开了圆圈但不应该仍然触发事件?

3 个答案:

答案 0 :(得分:2)

添加彼得所说的内容,如果您使用Grid.MouseDown事件并检查oldPoint是否在Ellipse内,然后处理了MouseMove事件,那么这种奇怪的行为不会被看到。

我还建议探索drag事件。

答案 1 :(得分:2)

您可以capture the mouse处理椭圆中的所有事件。

<Grid Name="grid1" Background="White">
    <Ellipse Height="50" HorizontalAlignment="Left" Margin="12,12,0,0" Name="ellipse1" Stroke="{x:Null}" VerticalAlignment="Top" Width="50" Fill="Black"
             MouseLeftButtonDown="ellipse1_MouseDown" MouseLeftButtonUp="ellipse1_MouseUp" />
</Grid>

这个代码隐藏在

之后
private void ellipse1_MouseDown(object sender, MouseButtonEventArgs e)
{
    Mouse.Capture(ellipse1);
    _oldPoint = e.GetPosition(grid1);
    ellipse1.MouseMove += new MouseEventHandler(ellipse1_MouseMove);
}

private void ellipse1_MouseUp(object sender, MouseButtonEventArgs e)
{
    Mouse.Capture(null);
    ellipse1.MouseMove -= new MouseEventHandler(ellipse1_MouseMove);
}

我已移动并将grid_MouseMove重命名为ellipse1_MouseMove。

答案 2 :(得分:1)

只要鼠标悬停在特定控件上,控件才会获取鼠标事件。

如果移动到新控件,鼠标将从旧控件中取消挂钩并挂钩到新控件。

有些方法可以创建一个附加到整个过程的全局钩子,但我想这不是我们所说的。