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

时间:2018-05-14 20:27:03

标签: c# wpf windows-10

我试图在我的辅助显示屏的右上角放置一个窗口。在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属性背后的模式。谢谢你的帮助。

3 个答案:

答案 0 :(得分: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 ;
}

答案 1 :(得分:0)

您可以执行以下操作

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的单位相同。这是一个非常狭窄的情况,但它可以推断到一般的定位。希望它能帮助你!

答案 2 :(得分:0)

也许我完全错了,但是我使用了不同 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;