C# WPF应用在最大化/最小化,移动到不同显示器后根据显示器大小自适应

12

我有两个显示器:

屏幕1:次要屏幕,分辨率为1920x1080

屏幕2:主要屏幕,分辨率为1600x900

屏幕1比屏幕2大。

当我在屏幕2中打开我的应用程序,然后将其从屏幕2移动到屏幕1并尝试最小化和最大化我的应用程序时,它最大化时会使用屏幕2的大小而不是当前显示器的大小(它不会根据显示器大小最大化)。

如何编辑我的代码,使其在最大化和最小化时根据应用程序当前所在的屏幕分辨率而不是主要显示器的分辨率进行最大化?

我在此线程中使用代码来进行调整大小:https://blogs.msdn.microsoft.com/llobo/2006/08/01/maximizing-window-with-windowstylenone-considering-taskbar/

这与此回答相同:https://dev59.com/rG025IYBdhLWcg3wVkYR#6315427

谢谢


你能展示一下你用来调整大小的代码吗? - Jeff R.
嗨@JeffR。我已经将代码添加到帖子中,谢谢。 - Zakk
你看过https://social.msdn.microsoft.com/Forums/vstudio/en-US/a78b04aa-40c8-4f87-8469-e786f8ecf17c/screen-resolution-issue-on-wpf-windowless-application?forum=wpf吗? - Dipen Shah
@Zakk 两个显示器的 DPI 不同吗?如果是,你需要先找到 DPI,然后根据 DPI 调整宽度、高度、上边距和左边距。 - Ankur Tripathi
DPI相同,分辨率不同@AnkurTripathi - Zakk
显示剩余3条评论
2个回答

4

要获取当前屏幕的大小,你可能需要使用Windows Forms方法FromHandle,如下所示:

using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;

namespace TestApp
{
    public partial class MainWindow : Window
    {           
        public Screen GetCurrentScreen(Window window)
        {
            return Screen.FromHandle(new WindowInteropHelper(window).Handle);
        }

        public MainWindow()
        {
            InitializeComponent();

            var screen = GetCurrentScreen(this);
            var height = screen.Bounds.Height;
            var width = screen.Bounds.Width;

            // ...
        }     
    }
}

另一种选择是订阅窗口的LocationChanged事件,以了解应用程序窗口何时移动到辅助屏幕,参见StepUp的此答案

FromHandle选项仅与获取应用程序所在屏幕的大小相关。我的问题是将应用程序从一个监视器移动到另一个监视器并尝试最大化后。第二个选项仅在我们只有2个监视器时有效。 - Zakk
@Zakk 看看这篇 CodeProject 文章(如果不行,可以看看这个和这个)。文章链接:https://www.codeproject.com/Tips/1184124/Get-Target-Screen-Size-of-the-Hosting-Window-in-WP - dontbyteme
@Zakk,你在这篇CodeProject文章中找到解决方案了吗? - dontbyteme
非常感谢!codeProject上的项目已经运行了。解决方案是添加OnLocationChangedEvent并在其中获取屏幕尺寸,就像该项目中一样。非常感谢您的帮助。 - Zakk

3

首先订阅状态改变事件:

public MainWindow()
{
   InitializeComponent();
   this.StateChanged += MainWindow_StateChanged;
}

然后只有在最小化之后,才能按照以下方式恢复虚拟/主屏幕大小: 而且我不知道您的默认应用程序大小是否是全屏,如果不是全屏,则可以通过SystemParameters屏幕大小轻松地恢复它们,需要一些逻辑。

private void MainWindow_StateChanged(object sender, EventArgs e)
{
   if (this.WindowState != WindowState.Minimized)
   {
                        this.Width = SystemParameters.PrimaryScreenWidth;
                        this.Height = SystemParameters.PrimaryScreenHeight;
                        //this.Width = SystemParameters.VirtualScreenWidth;
                        //this.Height =SystemParameters.VirtualScreenHeight;
                        //this.Width = SystemParameters.WorkArea.Width                            
                        //this.Height =SystemParameters.WorkArea.Height;
                     }
   }

为了应对这种情况,SystemParameters提供以下数据:

PrimeryScreenHeight/Width:

屏幕的高度/宽度。

VirtualScreenWidth/Height:

虚拟屏幕的宽度/高度。

WorkArea:

一个 RECT 结构,用于接收作业区坐标,以虚拟屏幕坐标表示。


这个 SystemParameter 在我将应用程序移动到第二个监视器并尝试最大化它时,是否会给我正确的大小?(即第二个监视器的大小) - Zakk
我刚刚编辑了我的答案,为您提供了更多细节。 由于我不确定哪个插头对应哪个,其中一个应该能解决问题, 如果您可以调试代码并在此处发布信息,这将会很有帮助。 - Or Yaacov
Primary和Workarea返回主屏幕大小。 VirtualScreen返回所有屏幕组合的宽度和高度。 - Zakk
如果您只有两个显示器,则长度将是虚拟长度减去主显示器的长度。您应该尝试一下,看看它是否解决了最小化和最大化问题,直到我编辑评论并提供多屏幕解决方案。 - Or Yaacov
嗨@Or Yaacov。以上解决方案对我有用,无论如何感谢你的帮助 :) - Zakk
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接