加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – WinForm在运行时改变大小……高DPI相关?

发布时间:2020-12-15 23:41:36 所属栏目:百科 来源:网络整理
导读:当我在 Windows中在视网膜MacBook Pro上的VM中运行我的WinForm应用程序时,表单的大小在运行时缩小,而按钮同时向外移动.这可能导致底部边缘的按钮滑到窗口边缘下方,看不见.由于它们是底部锚定的,因此它们完全无法访问.从Windows原生桌面运行时,该应用程序通常
当我在 Windows中在视网膜MacBook Pro上的VM中运行我的WinForm应用程序时,表单的大小在运行时缩小,而按钮同时向外移动.这可能导致底部边缘的按钮滑到窗口边缘下方,看不见.由于它们是底部锚定的,因此它们完全无法访问.从Windows原生桌面运行时,该应用程序通常表现良好.

只有表单上的Font或DPI AutoScaleMode设置才会出现这种情况.使用Inherit或None,表单及其内容很大,但与我设计它们的方式成正比.

我用一个来自模板的新模板WinForm应用程序重现了这一点,除了调整表单大小,只需按一下按钮就可以了.如何在不相对于彼此改变尺寸的情况下扩展应用程序?

这是designer.cs中的InitializeComponent()方法:

private void InitializeComponent()
  {
        this.sendButton = new System.Windows.Forms.Button();
        this.SuspendLayout();
        // 
        // sendButton
        // 
        this.sendButton.Location = new System.Drawing.Point(60,856);
        this.sendButton.Margin = new System.Windows.Forms.Padding(4);
        this.sendButton.MinimumSize = new System.Drawing.Size(200,60);
        this.sendButton.Name = "sendButton";
        this.sendButton.Size = new System.Drawing.Size(200,62);
        this.sendButton.TabIndex = 1004;
        this.sendButton.Text = "Send";
        this.sendButton.UseVisualStyleBackColor = true;
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(12F,25F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(282,981);
        this.Controls.Add(this.sendButton);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

  }

这是设计器中表单的屏幕截图:

Form at design time

并在运行时:

Form at runtime

解决方法

这个问题不是由重新缩放问题引起的,而是更为平凡.它是由 Form.SetBoundsCore() method引起的,我链接到问题陈述.

您可以使用SystemInformation类查看它,对边界应用约束,以便窗口不能太小并且不能大于监视器.此方法在您的程序中运行两次.第一次是表单的InitializeComponent()方法运行时.请注意,此时表单的大小仍然太大,在重新调整之前它不适合显示器.

也许你闻到了这个bug,它在通过ScaleControl()方法计算新大小之前过早地应用了大小约束.因此,您的设计Size.Height会被显示器的大小限制.然后缩放窗口以调整DPI差异,得到的高度太小.

通常你可以覆盖像SetBoundsCore()这样的虚方法,但是绕过base.SetBoundsCore()调用是不太实际的.在这种方法中发生了太多的东西,并绕过它可能会导致其他错误.实际的解决方法几乎无法提及.请注意链接代码除非将窗体的WindowState设置为normal,否则它不应用大小约束.因此,您可以通过在设计器中将WindowState设置为Minimized来绕过它.然后你要做的就是在Load事件中将它设置为normal,它会在窗口重新调整后触发:

protected override void OnLoad(EventArgs e) {
        this.WindowState = FormWindowState.Normal;
        base.OnLoad(e);
    }

嘿.扩大规模总是比缩小规模要麻烦得多.

我不能发布更典型的dpiAware代码.在这种情况下类似于:

protected override void OnLoad(EventArgs e) {
        this.ClientSize = new Size(button1.Width + 2 * button1.Left,button1.Bottom + 10);
        base.OnLoad(e);
    }

因此,只需强制客户区显示控件即可.你会选择底部的控件和最右边的控件.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读