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

WPF子窗口鼠标事件向主窗口传递:如何无标记阻止?

问题

点击主窗口的Canvas控件时,MouseLeftButtonDown事件触发并以模态方式打开子窗口;双击子窗口的ListView后关闭子窗口,此时主窗口的MouseLeftButtonUp事件会被意外触发。如何不使用额外标记变量的方式避免这种情况?

主窗口代码

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

    private void MouseLeftButtonDownCommand(object sender, MouseButtonEventArgs e)
    {
        ChildWindow childWindow = new ChildWindow();
        childWindow.Owner = this;
        childWindow.ShowDialog();
    }

    private void MouseLeftButtonUpCommand(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("Event Propagated to main window");
    }
}

主窗口XAML

<Grid>
    <Canvas Background="Transparent" MouseLeftButtonDown="MouseLeftButtonDownCommand" MouseLeftButtonUp="MouseLeftButtonUpCommand">
        
    </Canvas>
</Grid>

模态子窗口代码

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

    private void LeftDoubleClickCommand(object sender, MouseButtonEventArgs e)
    {
        this.Close();
    }
}

模态子窗口XAML

<Grid>
    <ListView Margin="10" MouseDoubleClick="LeftDoubleClickCommand">
        <ListViewItem Content="Coffie"></ListViewItem>
        <ListViewItem Content="Tea"></ListViewItem>
        <ListViewItem Content="Orange Juice"></ListViewItem>
        <ListViewItem Content="Milk"></ListViewItem>
        <ListViewItem Content="Iced Tea"></ListViewItem>
        <ListViewItem Content="Mango Shake"></ListViewItem>
    </ListView>
</Grid>

解决方案

方法1:在子窗口双击事件中标记事件已处理

修改子窗口的双击事件处理方法,先标记事件已处理再关闭窗口,阻止事件进一步传递:

private void LeftDoubleClickCommand(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
    this.Close();
}

方法2:主窗口按下时捕获鼠标,关闭后释放

在主窗口的MouseLeftButtonDown事件中让Canvas捕获鼠标,模态窗口关闭后释放捕获,确保鼠标释放事件只会被Canvas处理,不会在窗口切换后意外触发:

private void MouseLeftButtonDownCommand(object sender, MouseButtonEventArgs e)
{
    var canvas = sender as Canvas;
    canvas.CaptureMouse();
    
    ChildWindow childWindow = new ChildWindow();
    childWindow.Owner = this;
    childWindow.ShowDialog();
    
    canvas.ReleaseMouseCapture();
}

方法3:主窗口Up事件中判断鼠标位置

在主窗口的MouseLeftButtonUp事件里,检查鼠标是否在Canvas的可视范围内,只有在范围内才执行后续逻辑:

private void MouseLeftButtonUpCommand(object sender, MouseButtonEventArgs e)
{
    var canvas = sender as Canvas;
    Point mousePos = e.GetPosition(canvas);
    if (mousePos.X >= 0 && mousePos.X <= canvas.ActualWidth && 
        mousePos.Y >= 0 && mousePos.Y <= canvas.ActualHeight)
    {
        MessageBox.Show("Event Propagated to main window");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:38:14