You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击按钮按住鼠标时PreviewMouseMove事件失效的问题咨询

解决WPF中按住鼠标跨控件时无法获取Grid鼠标位置的问题

问题根源

按住鼠标点击红色Button时,Button会自动捕获鼠标(Mouse Capture),后续所有鼠标事件都会直接发送给Button,不再传递到BlueGrid,所以BlueGrid的PreviewMouseMove等事件无法触发。

解决方案

方案1:父容器全局监听,判断鼠标是否在BlueGrid内

修改XAML,给父Grid添加PreviewMouseMove事件:

<Grid PreviewMouseMove="ParentGrid_PreviewMouseMove">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0" Background="Red"></Button>
    <Grid Grid.Column="1" Name="BlueGrid" Background="Blue"></Grid>
</Grid>

后台代码实现:

private void ParentGrid_PreviewMouseMove(object sender, MouseEventArgs e)
{
    Point pos = Mouse.GetPosition(BlueGrid);
    // 检查鼠标是否处于BlueGrid的可视区域内
    if (pos.X >= 0 && pos.X <= BlueGrid.ActualWidth && pos.Y >= 0 && pos.Y <= BlueGrid.ActualHeight)
    {
        // 这里写你需要的鼠标位置处理逻辑
        // 示例:输出位置
        Console.WriteLine($"BlueGrid内鼠标坐标:X={pos.X}, Y={pos.Y}");
    }
}

方案2:手动管理Button的鼠标捕获,移出时释放

给Button添加MouseDown和MouseMove事件,在鼠标移出Button范围时释放捕获,让事件能正常传递到BlueGrid:
XAML修改:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0" Background="Red" MouseDown="Button_MouseDown" MouseMove="Button_MouseMove"></Button>
    <Grid Grid.Column="1" Name="BlueGrid" Background="Blue" PreviewMouseMove="Grid_PreviewMouseMove"></Grid>
</Grid>

后台代码:

private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
    ((Button)sender).CaptureMouse();
}

private void Button_MouseMove(object sender, MouseEventArgs e)
{
    Button btn = (Button)sender;
    Point posInBtn = Mouse.GetPosition(btn);
    // 判断鼠标是否已移出Button边界
    if (posInBtn.X < 0 || posInBtn.X > btn.ActualWidth || posInBtn.Y < 0 || posInBtn.Y > btn.ActualHeight)
    {
        btn.ReleaseMouseCapture();
    }
}

private void Grid_PreviewMouseMove(object sender, MouseEventArgs e)
{
    var pos = Mouse.GetPosition(BlueGrid);
    Console.WriteLine($"BlueGrid内鼠标坐标:X={pos.X}, Y={pos.Y}");
}

方案3:全局鼠标钩子(不推荐)

如果前两种方案无法满足需求,可通过Windows API实现全局鼠标钩子,但这种方式复杂度高,需要手动管理资源释放,仅在必须监听系统全局鼠标事件时考虑使用。

内容的提问来源于stack exchange,提问作者davood faezian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:32:31