PictureBox 未显示在第二个相同的表单上

PictureBox not showing on second identical form

我有一个 winforms 应用程序,它必须在特定条件下在两个屏幕上显示紧急消息。

这两条消息作为两个相同的表单传递,每个表单都在每个屏幕上实例化。每个表单都包含一个带有图像的可配置 PictureBox。

当条件满足时,两个窗体在两个屏幕上都正确启动,但是图片只在其中一个(主屏幕)显示,而另一个不显示。

表单在 foreach 上实例化,因此它们仅在不同的屏幕上使用相同的构造函数。

表格class:

public partial class FormClearingMessage : Form
{
    public FormClearingMessage(Screen s)
    {
        InitializeComponent();
        SetParameters(s);
    }

    private void SetParameters(Screen s)
    {
        this.Top = s.Bounds.Top;
        this.Left = s.Bounds.Left;
        this.Width = s.Bounds.Width;
        this.Height = s.Bounds.Height;
        this.pictureBox1.Top = this.Top + 20;
        this.pictureBox1.Left = this.Left + 20;
        this.pictureBox1.Width = this.Width - 40;
        this.pictureBox1.Height = this.Height - 40;
        this.pictureBox1.MaximumSize = new Size(this.pictureBox1.Width, this.pictureBox1.Height);
        this.LoadImage();  
    }

    private void LoadImage()
    {
                string imagePath = Utils.ResolveSymbolicPath(c.ReadCfgEntry("clearingMessage/imagePath", null));
                if (File.Exists(imagePath))
                    this.pictureBox1.Load(imagePath);
                else
                    throw new Exception();

    }
} 

初始化:

        // Initialize Clearing Message forms
        Screen[] screens = Screen.AllScreens;
        _clearingMessageForms = new List<FormClearingMessage>();

        foreach (Screen s in screens)
        {
            _clearingMessageForms.Add(new FormClearingMessage(s));
        }

满足条件时的说明:

                if (singleMessage.InformationType == _infoTypeForEmergency)
                {
                    if (_clearingMessageForms != null)
                   {
                        foreach (FormClearingMessage fcm in _clearingMessageForms)
                        {
                            if (!fcm.Visible)
                                this.Invoke(new Action(() =>     {
                                    fcm.Show();
                                }));           
                        }
                    }
                }

结果:

我似乎没有发现设置有任何问题,但显然我遗漏了一些东西,我希望有人能帮助我。

提前致谢!

在Windows中,有一个概念叫做"virtual screen"。当您只有一台显示器时,虚拟屏幕与物理屏幕完全相同,您可以忽略它。但是,当您有多个显示器时,它就开始变得重要了。

简而言之,虚拟屏幕是构成Windows桌面的所有显示器的边框。下图为示例——虚拟屏幕显示为灰色:

让事情变得棘手的是,出于兼容性原因,点 (0, 0) 始终位于 primary 监视器的左上角。因此,如果您的辅助显示器位于主显示器的右 and/or 底部,则它的坐标比主显示器大,一切正常。但是,如果您的辅助显示器位于主显示器的左侧 and/or 顶部,则其坐标为 负值

你的情况就是这种情况。右侧显示器显然设置为您的主显示器,因此其左上角的坐标为 (0, 0)。这意味着左侧监视器的坐标为 negative。因此,当您从对应的 Screen 对象的 Bounds 属性 中检索 TopLeft 属性时,您会得到负值。

如果您使用这些坐标来定位表单,这将是正确的,因为表单(和任何其他顶级 windows)使用虚拟屏幕坐标进行定位。

但是,您正在将 child 表单(即控件)定位在表单上。子 windows 使用 client 坐标,这是相对于父的。在客户端坐标中,父级的左上角始终位于 (0, 0),因此如果您希望 PictureBox 位于窗体的左上角,则应对其 Top 和 [=11 进行硬编码=] 属性为 0.

另见