如何在 WPF 中的多显示器显示器上定位窗口?

Posted

技术标签:

【中文标题】如何在 WPF 中的多显示器显示器上定位窗口?【英文标题】:How to position a window on multi-monitor displays in WPF? 【发布时间】:2018-10-24 14:20:19 【问题描述】:

我正在尝试在辅助显示屏的右上角放置一个窗口。在 Window_Loaded 事件处理程序中,我有以下代码:

private void Window_Loaded(object sender, RoutedEventArgs e)

    this.Left = Screen.AllScreens[1].WorkingArea.Left;
    this.Top = Screen.AllScreens[1].WorkingArea.Top;

当我的两个显示器的比例因子都为 100% 时,这非常有效,但是一旦我更改主显示器的比例,窗口就会完全加载到屏幕外。

有人知道在 WPF 中绝对定位窗口的方法吗?我找到的大多数答案都是Win8.1之前的,不必担心缩放问题。我似乎无法弄清楚 TopLeft 属性背后的模式。感谢您的帮助。

【问题讨论】:

【参考方案1】:

我在 CodeProject 上找到了解决这个问题的方法

Wpf windows on two screens

解决办法是计算真实分辨率与WorkingArea的分辨率的比值。

private void Window_Loaded(object sender, RoutedEventArgs e)

    var scaleRatio = Math.Max(Screen.PrimaryScreen.WorkingArea.Width / SystemParameters.PrimaryScreenWidth,
                Screen.PrimaryScreen.WorkingArea.Height / SystemParameters.PrimaryScreenHeight);
    this.Left = Screen.AllScreens[1].WorkingArea.Left / scaleRatio ;
    this.Top = Screen.AllScreens[1].WorkingArea.Top / scaleRatio ;

【讨论】:

当有多个具有不同缩放比例的显示器时,它是少数几个真正正确的解决方案之一。 需要System.Windows.Forms【参考方案2】:

您可以执行以下操作

private void Window_Loaded(object sender, RoutedEventArgs e)

    var p = this.PointFromScreen(new Point(Screen.AllScreens[1].WorkingArea.X, Screen.AllScreens[1].WorkingArea.Y));
    this.Left += p.X;
    this.Top += p.Y;

我发现 PointFromScreen 函数告诉您绝对坐标相对于窗口的偏移量。选择显示屏左上角的位置,您就会知道需要移动多少——但关键是它与窗口的TopBottom 采用相同的单位。这是一个非常狭窄的案例,但通常可以推断为定位。希望对您有所帮助!

【讨论】:

【参考方案3】:

也许我完全错了,但是我使用了不同 dpi 的屏幕(多显示器)中心并用尺子测量了它(不是开玩笑):

var handle = new System.Windows.Interop.WindowInteropHelper(this).Handle;
var screen = System.Windows.Forms.Screen.FromHandle(handle);
var scaleRatio = Math.Max(VisualTreeHelper.GetDpi(this).DpiScaleX, VisualTreeHelper.GetDpi(this).DpiScaleY);

this.Left = (screen.WorkingArea.Left + (screen.WorkingArea.Width - this.Width * scaleRatio) / 2) / scaleRatio;
this.Top = (screen.WorkingArea.Top + (screen.WorkingArea.Height - this.Height * scaleRatio) / 2) / scaleRatio;

并且 wpf 表单位于实际屏幕的中心。

将其放在左侧(在 Windows 10 上),那么解决方案是:

this.Left = screen.WorkingArea.Left/ scaleRatio - SystemParameters.ResizeFrameVerticalBorderWidth - SystemParameters.FixedFrameVerticalBorderWidth;

【讨论】:

以上是关于如何在 WPF 中的多显示器显示器上定位窗口?的主要内容,如果未能解决你的问题,请参考以下文章

SDL2如何在第二台显示器上定位窗口?

在 WPF 的网格中显示对其他控件的控件

我在用VB写WPF程序,有一个窗口显示的问题

Windows 10中的第二个屏幕上的WPF窗口对象被涂黑

wpf 怎么在窗口里面显示一个窗口!

wpfwindow.show字体不显示