[英]WinForm changes size at runtime… high DPI related?
當我在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()方法引起的,我鏈接到問題語句。
您可以使用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);
}
因此,只需強制客戶區顯示控件即可。 你會選擇底部的控件和最右邊的控件。
我認為問題是AutoScaleMode。 對Form1中的代碼進行以下更改:
this.AutoScaleDimensions = new System.Drawing.Size(96, 96);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
這可能會解決您的問題。 SizeF
用於Font
,對於100%字體大小,其值為(13F, 8F)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.