WPF在CaptureMouse()之后不发送MouseMove事件;

时间:2010-08-02 09:11:13

标签: wpf canvas mousemove

我正在尝试使用带有圆角矩形的WPF画布,我可以使用鼠标拖动它。然而,一旦我尝试在画布上捕获鼠标,我就不再获得移动事件了。

这是一个“mycanvas”用户控件,矩形是“foo”用户控件。这些(减去序言)的XAML是:

mycanvas.xaml:

<Canvas MouseDown="CanvasMouseDown" MouseMove="CanvasMouseMove" MouseUp="CanvasMouseUp" Background="White">

    <my:Foo HorizontalAlignment="Left" Canvas.Left="97" Canvas.Top="30" x:Name="m_foo" VerticalAlignment="Top" Height="87" Width="128" />
</Canvas>

foo.xaml:

<Border BorderThickness="2" BorderBrush="Black" CornerRadius="15" Background="Plum">
    <Grid>
        <Label Content="Foo" Height="28" HorizontalAlignment="Left" Margin="6,6,0,0" Name="label1" VerticalAlignment="Top" />
    </Grid>
</Border>

然后处理程序是: mycanvas.xaml.cs:

private void CanvasMouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.Source is Foo)
    {
        m_moving = e.Source as Foo;
        CaptureMouse();
        e.Handled = true;
    }
}

private void CanvasMouseMove(object sender, MouseEventArgs e)
{
    if (m_moving != null)
    {
        Canvas.SetLeft(m_moving, e.GetPosition(this).X);
        Canvas.SetTop(m_moving, e.GetPosition(this).Y);
    }
}

private void CanvasMouseUp(object sender, MouseButtonEventArgs e)
{
    ReleaseMouseCapture();
    m_moving = null;
}

MouseDown会激活,因此CaptureMouse会被调用(并且因为我无法再关闭应用程序或单击其中任何其他内容而工作!)但MouseMove再也不会被调用 - 那么MouseMove事件现在在哪里被发送? ?

如果我alt-tab到另一个应用程序,然后现在回到现在突然调用MouseMove并且Foo随鼠标移动。

2 个答案:

答案 0 :(得分:8)

尝试:

Mouse.Capture(this, CaptureMode.SubTree);

m_moving.CaptureMouse();
...
if (m_moving != null)
{
    m_moving.ReleaseMouseCapture();
    m_moving = null;
}

鼠标事件由Foo引发,而不是由Canvas引发,因此当您使用Canvas捕获鼠标时,可以防止它们被引发。

答案 1 :(得分:1)

您可以直接在Window上使用MouseMove事件:

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

        this.MouseMove += MouseEventHandler;

    }

    private void MouseEventHandler(Object sender, MouseEventArgs e)
    {
        System.Windows.Point position = e.GetPosition(this);

        Canvas.SetLeft(ElipseElement, position.X-5);
        Canvas.SetTop(ElipseElement, position.Y-5);    


    }
}