c# – WinForm在运行时改变大小……高DPI相关?
当我在
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.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); } 因此,只需强制客户区显示控件即可.你会选择底部的控件和最右边的控件. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |