如何捕获WPF窗口外部点击事件?Deactivated事件未触发求助
问题解决:WPF无样式窗口点击外部关闭失败的问题
你遇到的Deactivated事件不触发的核心原因是:当窗口设置WindowStyle.None且ShowInTaskbar=false时,系统不会为这类窗口维护标准的激活状态切换逻辑,点击窗口外部时,窗口并不会触发Deactivated事件,所以你的绑定代码无法生效。
下面给出两种可行的替代方案:
方案一:鼠标捕获+点击位置判断
通过捕获鼠标,在鼠标抬起时判断点击位置是否在窗口范围内,不在则关闭窗口:
var wndPpList = new Window() { SizeToContent = SizeToContent.WidthAndHeight, WindowStyle = WindowStyle.None, ShowInTaskbar = false, BorderBrush = GetColour_Cyan(), BorderThickness = new Thickness(3), }; wndPpList.CaptureMouse(); wndPpList.MouseUp += (sender, e) => { var window = sender as Window; if (window == null) return; // 获取鼠标在屏幕坐标系的位置 var mouseScreenPos = Mouse.GetPosition(null); // 计算窗口在屏幕上的矩形范围 var windowScreenRect = new Rect(window.Left, window.Top, window.ActualWidth, window.ActualHeight); // 如果点击位置不在窗口内,则关闭 if (!windowScreenRect.Contains(mouseScreenPos)) { window.ReleaseMouseCapture(); window.Close(); } };
方案二:监听全局鼠标点击事件
通过注册应用级别的鼠标点击事件,判断点击是否发生在目标窗口外部,触发关闭:
var wndPpList = new Window() { SizeToContent = SizeToContent.WidthAndHeight, WindowStyle = WindowStyle.None, ShowInTaskbar = false, BorderBrush = GetColour_Cyan(), BorderThickness = new Thickness(3), }; wndPpList.Loaded += (sender, e) => { var targetWindow = sender as Window; // 注册全局预览鼠标点击事件 Application.Current.PreviewMouseDown += (s, args) => { // 窗口已不可见时取消事件绑定 if (targetWindow == null || !targetWindow.IsVisible) { Application.Current.PreviewMouseDown -= (s, args); return; } var mouseScreenPos = args.GetPosition(null); var windowScreenRect = new Rect(targetWindow.Left, targetWindow.Top, targetWindow.ActualWidth, targetWindow.ActualHeight); if (!windowScreenRect.Contains(mouseScreenPos)) { targetWindow.Close(); Application.Current.PreviewMouseDown -= (s, args); } }; };
两种方案都能实现"点击窗口外部自动关闭"的需求,方案一更轻量,方案二则适用于窗口内有需要捕获鼠标的控件这类复杂场景。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

