WPF 多显示器问题 - WindowState

发布于 2024-08-16 03:01:32 字数 1068 浏览 3 评论 0原文

一段时间以来,我一直在尝试让我的 WPF 应用程序跨多个显示器,并且几乎可以正常工作。

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

win1.WindowState = WindowState.Maximized

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

我的代码如下:

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();
    }
}

在窗口 1 内部:

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

    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Maximized;
    }
}

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

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

这是为什么呢?

I've been trying to get my WPF application to span multiple monitors for some time now and nearly have it working.

The problem seems to arise when I set the following line:

win1.WindowState = WindowState.Maximized

This causes the application to span only the primary screen.

My code is as follows:

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();
    }
}

And inside of Window 1:

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

    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Maximized;
    }
}

This example works, but the window is not maximized, and the application borders are still visible.

Including the maximized deceleration in Application_Startup makes the monitor maximize to the primary monitor.

Why is this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情场扛把子 2024-08-23 03:01:32

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

另请注意,仅在两种情况下才可以使用单个矩形窗口跨越两个显示器:

  1. 两个显示器具有相同的高度并配置为并排,或者
  2. 两个显示器具有相同的宽度并配置为位于上方及以下。

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

好的,以下是如何获取定位窗口所需的信息:

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

  1. 将 MONITORINFO 结构声明为 C# 中的结构
  2. 为 EnumDisplayMonitors 和 GetMonitorInfo 声明 DllImports(两者均在 User32.dll 中找到)
  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;
}

获得显示器坐标后,使用您选择的算法来选择要创建的窗口数量以及每个窗口的坐标。然后使用明确的大小和位置创建窗口。

请注意,您可能希望使用 rcWork 而不是 rcMonitor,这样您就不会覆盖开始菜单等。

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

First note that the concept of "Maximized" is tied to a single monitor, so you cannot truly have a maximized window on multiple monitors. Of course in WPF you can create your own window frame and draw anything you like in it, so if you want you can certainly make the user think the window is maximized and spanning multiple screens.

Also note that it is possible to span two monitors with a single rectangular window in only two cases:

  1. The two monitors have the same height and are configured to be side by side, or
  2. The two monitors have the same width and are configured to be above and below.

Otherwise you will need to use two separate windows to cover the entire surfaces of both monitors, or use a large window that includes areas that aren't covered by any monitor.

Ok, here's how to get the information you'll need to position your window(s):

WPF itself does not provide a way to ask about your monitor count, resolutions, or relative positions. Fortunately we can call Win32 directly using [DllImport]. To get monitor resolutions and layouts, just:

  1. Declare the MONITORINFO struct as a struct in C#
  2. Declare DllImports for EnumDisplayMonitors and GetMonitorInfo, both found in User32.dll
  3. Write a method that calls EnumDisplayMonitors and passes a delegate that gets the monitor info and returns it in a list.

Here is the basic idea:

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;
}

Once you have the monitor coordinates, use an algorithm of your choice to select how many window(s) you want to create and what coordinates you want for each one. Then create the windows using explicit size(s) and location(s).

Note that you'll probably want to use rcWork as opposed to rcMonitor so you don't overwrite the start menu, etc.

Also note that in many cases some of the coordinates returned will be negative, for example if the secondary monitor is to the left of the primary monitor. This is not a problem: Just use the coordinates as given and your windows will appear in the correct places.

阳光下慵懒的猫 2024-08-23 03:01:32

如果您始终可以假设辅助显示器的分辨率与主显示器的分辨率相同,则可以实现如下所示的操作:

//当你关心任务栏高度时使用这个
矩形工作区域 = SystemParameters.WorkArea;
this.Width = SystemParameters.PrimaryScreenWidth * 2;
this.Height = workArea.Bottom;
这个.Left = 0;
这.顶部= 0;

或者:

// 当你不关心任务栏高度时使用这个
this.Width = SystemParameters.PrimaryScreenWidth * 2;
this.Height = SystemParameters.PrimaryScreenHeight;
这个.Left = 0;
这.顶部= 0;

If you can always assume that your secondary monitor is at the same resolution as the primary, you could implement something like this:

// Use this is you are concerned about the taskbar height
Rect workArea = SystemParameters.WorkArea;
this.Width = SystemParameters.PrimaryScreenWidth * 2;
this.Height = workArea.Bottom;
this.Left = 0;
this.Top = 0;

Or:

// Use this is you don't care about the taskbar height
this.Width = SystemParameters.PrimaryScreenWidth * 2;
this.Height = SystemParameters.PrimaryScreenHeight;
this.Left = 0;
this.Top = 0;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文