求助:对话框及遮罩窗口在副显示器打开而非主应用所在显示器
解决WPF遮罩窗口与弹窗跨显示器显示问题
你遇到的问题是主窗口在显示器1,但遮罩和弹窗错误显示在显示器2,以下是修复方案:
问题根源
多显示器场景下,仅设置Owner和CenterOwner可能无法正确绑定主窗口所在的屏幕,尤其是主窗口处于最大化状态时,手动设置的Top/Left参数可能不准确,导致窗口跳转到其他显示器。
修复后的代码
public void ShowModalWindow(Window window) { if (window == null) return; var mainWindow = Application.Current.MainWindow; // 获取主窗口所在的屏幕信息 var mainWindowHandle = new System.Windows.Interop.WindowInteropHelper(mainWindow).Handle; var mainScreen = System.Windows.Forms.Screen.FromHandle(mainWindowHandle); var screenWorkingArea = mainScreen.WorkingArea; Window modalWindow = new Window { Owner = mainWindow, // 手动指定位置,避免多显示器下的偏移 WindowStartupLocation = WindowStartupLocation.Manual, Left = screenWorkingArea.Left, Top = screenWorkingArea.Top, Width = screenWorkingArea.Width, Height = screenWorkingArea.Height, WindowState = WindowState.Normal, WindowStyle = WindowStyle.None, ResizeMode = ResizeMode.NoResize, ShowInTaskbar = false, AllowsTransparency = true, Background = Brushes.Black, Opacity = 0.7, Topmost = true // 确保遮罩始终在主窗口上方 }; // 给主窗口添加模糊效果 mainWindow.Effect = new BlurEffect { Radius = 5, KernelType = KernelType.Gaussian }; modalWindow.Show(); // 弹窗绑定到遮罩窗口,确保在同一屏幕居中显示 window.Owner = modalWindow; window.WindowStartupLocation = WindowStartupLocation.CenterOwner; window.ShowDialog(); // 恢复主窗口状态 mainWindow.Effect = null; modalWindow.Close(); mainWindow.Focus(); }
关键修改说明
- 绑定主窗口所在屏幕:通过
System.Windows.Forms.Screen获取主窗口对应的显示器工作区,确保遮罩覆盖整个目标显示器。 - 手动控制窗口位置:将遮罩的
WindowStartupLocation设为Manual,基于屏幕工作区的坐标设置位置,避免自动居中逻辑在多显示器下出错。 - 强制遮罩层级:添加
Topmost = true保证遮罩始终显示在主窗口上方,不会被其他窗口遮挡。 - 弹窗居中逻辑:弹窗绑定到遮罩窗口,使用
CenterOwner确保在同一屏幕居中,而非系统默认的主屏幕。
注意:需要在项目中添加对
System.Windows.Forms程序集的引用,才能使用Screen类。
内容的提问来源于stack exchange,提问作者Md. Zakir Hossain
相关产品推荐
相关产品推荐

