WPF多监视器问题 - WindowState

Mig*_*Mig 4 wpf multiple-monitors

我一直试图让我的WPF应用程序跨越多个监视器一段时间,并且几乎让它工作.

当我设置以下行时,似乎出现了这个问题:

win1.WindowState = WindowState.Maximized
Run Code Online (Sandbox Code Playgroud)

这会导致应用程序仅跨越主屏幕.

我的代码如下:

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        Window1 win1 = new Window1();
        win1.WindowStartupLocation = WindowStartupLocation.Manual;
        win1.Width = 2560;
        win1.Height = 1024;
        win1.Left = 0;
        win1.Top = 0;
        win1.Topmost = true;
        win1.Background = new SolidColorBrush(Colors.Black);
        win1.WindowStyle = WindowStyle.None;
        win1.Show();
        win1.Focus();
    }
}
Run Code Online (Sandbox Code Playgroud)

在窗口1内:

public partial class Window1 : Window
{
    public Window1()
    {

    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Maximized;
    }
}
Run Code Online (Sandbox Code Playgroud)

此示例有效,但窗口未最大化,应用程序边框仍然可见.

在Application_Startup中包含最大化减速度使监视器最大化到主监视器.

为什么是这样?

Ray*_*rns 11

首先请注意,"最大化"的概念与单个监视器相关联,因此您无法在多个监视器上真正拥有最大化窗口.当然在WPF中,您可以创建自己的窗口框架并在其中绘制任何您喜欢的内容,因此如果您需要,您当然可以让用户认为窗口最大化并跨越多个屏幕.

另请注意,只有两种情况可以跨越两个带有单个矩形窗口的监视器:

  1. 两个显示器具有相同的高度,并配置为并排,或
  2. 两个监视器具有相同的宽度,并配置为高于和低于.

否则,您将需要使用两个单独的窗口来覆盖两个监视器的整个表面,或者使用包含任何监视器未覆盖的区域的大窗口.

好的,这里是如何获取您需要的信息来定位您的窗口:

WPF本身并不提供询问您的监视器数量,分辨率或相对位置的方法.幸运的是,我们可以使用[DllImport]直接调用Win32.要获得显示器分辨率和布局,只需:

  1. 将MONITORINFO结构声明为C#中的结构
  2. 为User32.dll中的EnumDisplayMonitors和GetMonitorInfo声明DllImports
  3. 编写一个调用EnumDisplayMonitors的方法,并传递一个获取监视器信息的委托并将其返回到列表中.

这是基本的想法:

List<MONITORINFO> GetAllMonitorInfo()
{
  var result = List<MONITORINFO>();
  EnumDisplayMonitors(null, null,
    (hMonitor, hdcMonitor, lprcMonitor, dwData) =>
    {
      var info = new MONITORINFO { cbSize = Marshall.Sizeof(typeof(MONITORINFO)) };
      GetMonitorInfo(hMonitor, ref info);
      result.Add(info);
    }, null);
  return result;
}
Run Code Online (Sandbox Code Playgroud)

获得监视器坐标后,使用您选择的算法选择要创建的窗口数以及每个窗口所需的坐标.然后使用显式大小和位置创建窗口.

请注意,您可能希望使用rcWork而不是rcMonitor,因此您不会覆盖开始菜单等.

另请注意,在许多情况下,返回的某些坐标将为负数,例如,如果辅助监视器位于主监视器的左侧.这不是问题:只需使用给定的坐标,您的窗口就会显示在正确的位置.

  • 是的,使用System.Windows.Forms.Screen类比直接调用本机方法更好. (2认同)