C# Windows窗体始终在主监视器上启动

C# Windows窗体始终在主监视器上启动,c#,winforms,C#,Winforms,我支持用C#编写并在windows窗体上运行的桌面应用程序。在整个应用程序中,应用程序有许多弹出表单(通常通过单击按钮启动)。我收到了用户的请求,允许他们选择要从哪个监视器启动应用程序(默认情况下),并保存该信息的存储。随着新冠病毒-19的流行,我的公司面临着很多员工在家工作的局面。一个典型的设置是用户带着笔记本电脑,可能插在通用扩展底座上,并连接了第二台显示器。用户希望应用程序在第二台显示器上启动,而不是在主显示器(笔记本电脑的显示器)上启动 当我将默认监视器设置为第二个(非主)监视器时,似乎

我支持用C#编写并在windows窗体上运行的桌面应用程序。在整个应用程序中,应用程序有许多弹出表单(通常通过单击按钮启动)。我收到了用户的请求,允许他们选择要从哪个监视器启动应用程序(默认情况下),并保存该信息的存储。随着新冠病毒-19的流行,我的公司面临着很多员工在家工作的局面。一个典型的设置是用户带着笔记本电脑,可能插在通用扩展底座上,并连接了第二台显示器。用户希望应用程序在第二台显示器上启动,而不是在主显示器(笔记本电脑的显示器)上启动

当我将默认监视器设置为第二个(非主)监视器时,似乎遇到了问题。大多数表单将从辅助监视器启动,但并非所有表单都将从辅助监视器启动。在这一点上,这对我来说是一个谜,因此这篇文章。例如,对于启动给定表单的两个不同表单,我有完全相同的代码。一个将在当前监视器(第二个监视器)上启动。另一种形式将坚持在主监视器上启动。这是我试过的代码

//above this point, I'm passing in parameters
逐步浏览代码,以下是我将鼠标悬停在代码中的字段上时看到的内容:

screen- {Bounds = {{X=1600,Y=0,Width=1440,Height=900}} WorkingArea = {{X=0,Y=0,Width=0,Height=0}} Primary = false DeviceName = "\\\\.\\DISPLAY7"}
那绝对是第二屏

同样,应该在屏幕上启动#2

我也尝试过(而不是那4行代码):

getIndexofSelectedMonitor()是我构建的一个函数,用于检索已保存监视器的索引(本例中为1)

我还努力编写了解决方案:

myform.StartPosition = FormStartPosition.Manual;
myform.Location = Screen.AllScreens[1].WorkingArea.Location;
然后,在这3个部分的下面,我启动了新表单,其中包括:

myform.ShowDialog();

在所有情况下,表单都坚持在主监视器上启动,我不知道为什么。感谢您的帮助

此代码适用于我:

只需创建一个新的Windows窗体应用程序,然后按如下方式替换Form1代码:

public partial class Form1 : Form
{
    FlowLayoutPanel flowLayoutPanel1;

    public Form1()
    {
        InitializeComponent();

        flowLayoutPanel1 = new FlowLayoutPanel();
        flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
        Controls.Add(flowLayoutPanel1);
        foreach (var screen in Screen.AllScreens)
        {
            Button button = new Button();
            button.Size = new Size(128, 64);
            button.Text = screen.DeviceName;
            button.Click += (object sender, EventArgs e) =>
            {
                Form form = new Form();
                form.Text = screen.DeviceName;
                form.StartPosition = FormStartPosition.Manual;
                form.Bounds = screen.Bounds;
                form.Show();
            };
            flowLayoutPanel1.Controls.Add(button);
        }
    }
}
这将创建一个应用程序,为每个屏幕创建一个按钮,根据设备名称命名。单击按钮将在该屏幕上创建默认的空白表单

诀窍是设置
form.Bounds
并将
form.StartPosition
设置为
FormStartPosition.Manual


您也可以将表单的
WindowState
设置为
WindowState.Maximized
,如果您愿意的话。

我在这里回答我自己的问题。Wyck提出了上述正确的问题,以发布复制该行为的完整表单。我发布所有代码的问题是代码太多(这个应用程序已经存在了20年)。所以,我做了第二件最好的事情,我仔细检查了每一行代码。我发现,在加载新表单时,我的一个前辈有一个名为CenterForm()的方法,该方法重写了我的代码,并将表单放在主屏幕上


我在这里学到了两个教训。1) 始终查看完整的代码。在我的情况下,问题是在我所处的位置的下游,我已经确定了我的重点。2) 您真的不需要上面的所有代码来让表单显示在不同的监视器上。您只需通过StartPosition“CenterParent”设置即可对此进行控制。一旦我删除了所有其他代码,这是我必须在每个表单上设置的唯一内容。

您是否尝试更改主监视器以确认它确实遵循主监视器?只是好奇。你最终显示的表单是否与你重新定位的表单相同?显示创建myform的代码和显示myform的代码。告诉我们代码是什么类的in@DougDawson如果我将默认监视器更改为主监视器(笔记本电脑监视器),则一切都会正常工作。当我使用第二个监视器作为默认监视器进行测试时,我注意到并非所有表单的工作方式都相同,但代码都相同。因此,本质上,一些(但不是全部)表单坚持在主监视器上启动,而不管我告诉它在辅助监视器上启动。检查此项:。使您的应用程序成为DpiAware,然后验证VirtualScreen属性。使用所述方法之一获取屏幕坐标和监视器,以确定表单实际显示的位置或您希望显示表单的位置。-您的
\\.\DISPLAY7
(屏幕2?)有一个有趣的工作区域。谢谢您的回复。我尝试了一个与我的原始代码混合的解决方案版本。边界似乎是我没有的一块。当我设置myform.Bounds=screen.Bounds时,我得到的是错误屏幕上的一个更大的表单,所以不幸的是,同样的问题。很有趣!也许您可以与我们共享您的桌面设置?确切的屏幕数量、分辨率和位置。以及您是否正在使用类似NVIDIA的马赛克模式(根据windows,使多个显示器像一个显示器一样工作)。你能更具体地说“大”和“错”吗?多大?哪个屏幕?我的代码在空白应用程序中也会失败,还是只有在“与原始代码混合”时才会失败?因为它对我很有效。所以肯定有一个谜要解开。在你的问题中尽可能多地透露细节。这是一台插入通用扩展底座的笔记本电脑。通用扩展底座上连接有鼠标、键盘和显示器。关于:显示器设置下的两台显示器-笔记本电脑是左边的显示器,第二台显示器是右边的显示器。@noel我根本无法重现您的结果。你能帮我重现你的问题吗?发布一个完整的Form1.cs,复制您看到的行为。感谢您的确认。我经常发现,编写一个完全详细的问题并将其分解为一个最小的/自包含的复制,与使用调试器进行调试一样有效。看来你吸取了宝贵的教训。很高兴你又开始跑步了。
myform.StartPosition = FormStartPosition.Manual;
myform.Location = Screen.AllScreens[1].WorkingArea.Location;
myform.ShowDialog();
public partial class Form1 : Form
{
    FlowLayoutPanel flowLayoutPanel1;

    public Form1()
    {
        InitializeComponent();

        flowLayoutPanel1 = new FlowLayoutPanel();
        flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
        Controls.Add(flowLayoutPanel1);
        foreach (var screen in Screen.AllScreens)
        {
            Button button = new Button();
            button.Size = new Size(128, 64);
            button.Text = screen.DeviceName;
            button.Click += (object sender, EventArgs e) =>
            {
                Form form = new Form();
                form.Text = screen.DeviceName;
                form.StartPosition = FormStartPosition.Manual;
                form.Bounds = screen.Bounds;
                form.Show();
            };
            flowLayoutPanel1.Controls.Add(button);
        }
    }
}