眾所周知,WinForm采用基于像素的布局模型。
因此,原生WinForm對于窗體自適應支持不是很好。
但是我們也可以通過代碼來實現。
今天跟大家分享一下如何實現WinForm窗體自適應。
當我們想要實現窗體自適應的時候,優先要通過界面布局設置好窗體和控件的一些屬性:1、Anchor:用于固定控件的邊緣到窗體的邊緣,當窗體大小改變時,控件的位置也會相應改變。2、Dock:用于將控件停靠到窗體的邊緣,控件的大小會隨著窗體邊緣的改變而改變。
3、布局控件:使用 TableLayoutPanel
或 FlowLayoutPanel
等布局控件可以更好地管理控件的布局,它們可以自動調整大小和位置。
4、Padding:Padding屬性定義控件內部的一段空間,用于將控件的內容保持在距控件邊框一定的距離。5、Margin:Margin屬性定義控件周圍的空間,該空間使其他控件與控件的邊框保持指定距離。
除了以上方法外,在實際應用中,我們更多會使用通過代碼來手動調整窗體和控件的大小和位置,這種方法第一次寫的時候會麻煩一些,但是封裝好之后,后續應用也比較簡單。
一、我們創建一個類FormAutoSize,然后創建三個字段,分別是窗體寬度、高度和窗體對象。
public class FormAutoSize
{
//窗體對象
private Form form;
//定義當前窗體的寬度
private float width;
//定義當前窗體的高度
private float height;
}
二、在FormAutoSize類的構造方法中,初始化寬度、高度和窗體對象,同時將各個控件的寬度、高度、左邊距、上邊距以及字體大小,按照指定的格式(這里使用分號拼接)存儲到AccessibleDescription屬性里,因為AccessibleDescription屬性很少使用,所以存儲到這個屬性里。
private void SetDescription(Control cons)
{
foreach (Control ctl in cons.Controls)
{
ctl.AccessibleDescription = ctl.Width + ";" + ctl.Height + ";" + ctl.Left +
";" + ctl.Top + ";" + ctl.Font.Size;
if (ctl.Controls.Count > 0)
{
SetDescription(ctl);
}
}
}
public FormAutoSize(Form form)
{
this.form = form;
width = this.form.Width;
height = this.form.Height;
SetDescription(this.form);
}
三、接下來就是如何重置窗體控件布局,這里將當前的寬度高度與初始寬度高度進行相除,會得到比例系數scaleX/scaleY,然后將這個系數疊加進去,得到新的寬度高度等屬性值,然后重新設置控件屬性即可。
private void SetControls(float scaleX, float scaleY, Control cons)
{
//遍歷窗體中的控件,重新設置控件的值
foreach (Control con in cons.Controls)
{
//獲取控件的AccessibleDescription屬性值,并分割后存儲字符串數組
if (con.AccessibleDescription != null)
{
var tag = con.AccessibleDescription.ToString().Split(';');
//根據窗體縮放的比例確定控件的值
con.Width = Convert.ToInt32(Convert.ToSingle(tag[0]) * scaleX); //寬度
con.Height = Convert.ToInt32(Convert.ToSingle(tag[1]) * scaleY); //高度
con.Left = Convert.ToInt32(Convert.ToSingle(tag[2]) * scaleX); //左邊距
con.Top = Convert.ToInt32(Convert.ToSingle(tag[3]) * scaleY); //頂邊距
var currentSize = Convert.ToSingle(tag[4]) * scaleY; //字體大小
if (currentSize > 0)
{
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
}
con.Focus();
if (con.Controls.Count > 0)
{
SetControls(scaleX, scaleY, con);
}
}
}
}
/// <summary>
/// 重置窗體布局
/// </summary>
public void ResumeLayout()
{
var scaleX = form.Width / width;
var scaleY = form.Height / height;
SetControls(scaleX, scaleY, form);
}
四、最后一步就是如何進行調用:首先在需要進行縮放的窗體中定義一個FormAutoSize對象,然后在構造方法中實例化該對象,將當前窗體this作為參數傳遞進去,最后在窗體的SizeChanged事件中調用該對象的ResumeLayout方法。
private FormAutoSize formAutoSize;
public FrmMain()
{
InitializeComponent();
formAutoSize = new FormAutoSize(this);
this.SizeChanged += (sender, e) =>
{
formAutoSize.ResumeLayout();
};
}
五、測試效果:
縮放前尺寸:1280*720
縮放后尺寸:1420*827
閱讀原文:原文鏈接
該文章在 2025/3/21 10:32:43 編輯過