3 回答

TA貢獻(xiàn)2036條經(jīng)驗(yàn) 獲得超8個(gè)贊
假定您不嘗試遵循用戶的UI字體選擇(SystemFonts.IconTitleFont),并且僅將表單硬編碼為一種字體大?。ɡ鏣ahoma 8pt,Microsoft Sans Serif 8.25pt),則可以將表單設(shè)置AutoScaleMode為ScaleMode.Dpi。
這將通過(guò)調(diào)用來(lái)按比例縮放表單及其大部分子控件的大小,從而依次對(duì)自身和所有子控件遞歸調(diào)用protected 方法。將根據(jù)新縮放因子的需要增加控件的位置,大小,字體等。CurrentDpiSetting / 96Form.Scale()ScaleControl()ScaleControl
警告:并非所有控件都能正確縮放自己。例如,列表視圖的列不會(huì)隨著字體變大而變寬。為了處理該問(wèn)題,您必須根據(jù)需要手動(dòng)執(zhí)行其他縮放。我通過(guò)重寫(xiě)受保護(hù)的ScaleControl()方法并手動(dòng)縮放listview列來(lái)做到這一點(diǎn):
public class MyForm : Form
{
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
Toolkit.ScaleListViewColumns(listView1, factor);
}
}
public class Toolkit
{
/// <summary>
/// Scale the columns of a listview by the Width scale factor specified in factor
/// </summary>
/// <param name="listview"></param>
/// <param name="factor"></param>
/// <example>/*
/// protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
/// {
/// base.ScaleControl(factor, specified);
///
/// //ListView columns are not automatically scaled with the ListView, so we
/// //must do it manually
/// Toolkit.ScaleListViewColumns(lvPermissions, factor);
/// }
///</example>
public static void ScaleListViewColumns(ListView listview, SizeF factor)
{
foreach (ColumnHeader column in listview.Columns)
{
column.Width = (int)Math.Round(column.Width * factor.Width);
}
}
}
如果您僅使用控件,那么這一切都很好。但是,如果您使用任何硬編碼的像素大小,則需要通過(guò)表單的當(dāng)前縮放比例來(lái)縮放像素的寬度和長(zhǎng)度。可能具有硬編碼像素大小的情況的一些示例:
畫(huà)一個(gè)25px高的矩形
在表單上的位置(11,56)繪制圖像
將圖標(biāo)拉伸到48x48
使用Microsoft Sans Serif 8.25pt繪制文本
獲取圖標(biāo)的32x32格式并將其填充到PictureBox中
如果是這種情況,則需要通過(guò)“ 當(dāng)前縮放系數(shù) ” 縮放那些硬編碼的值。不幸的是,沒(méi)有提供“當(dāng)前”比例因子,我們需要自己記錄它。解決方案是假設(shè)初始比例因子為1.0,并且每次ScaleControl()調(diào)用該比例因子時(shí),請(qǐng)通過(guò)新因子修改運(yùn)行比例因子。
public class MyForm : Form
{
private SizeF currentScaleFactor = new SizeF(1f, 1f);
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
//Record the running scale factor used
this.currentScaleFactor = new SizeF(
this.currentScaleFactor.Width * factor.Width,
this.currentScaleFactor.Height * factor.Height);
Toolkit.ScaleListViewColumns(listView1, factor);
}
}
最初,比例因子為1.0。如果form然后被縮放1.25,則縮放因子變?yōu)椋?/p>
1.00 * 1.25 = 1.25 //scaling current factor by 125%
如果該表單隨后被縮放0.95,則新的縮放因子變?yōu)?/p>
1.25 * 0.95 = 1.1875 //scaling current factor by 95%
使用a的原因SizeF(而不是單個(gè)浮點(diǎn)值)是因?yàn)榭s放量在x和y方向上可以不同。如果將表單設(shè)置為ScaleMode.Font,則該表單將縮放為新的字體大小。字體可以具有不同的寬高比(例如, Segoe UI的字體比Tahoma的字體高)。這意味著您必須分別縮放x和y值。
因此,如果您想將控件放置在location (11,56),則必須將定位代碼從以下位置更改:
Point pt = new Point(11, 56);
control1.Location = pt;
至
Point pt = new Point(
(int)Math.Round(11.0*this.scaleFactor.Width),
(int)Math.Round(56.0*this.scaleFactor.Height));
control1.Location = pt;
如果要選擇字體大小,則同樣適用:
Font f = new Font("Segoe UI", 8, GraphicsUnit.Point);
必須成為:
Font f = new Font("Segoe UI", 8.0*this.scaleFactor.Width, GraphicsUnit.Point);
而將32x32圖標(biāo)提取到位圖的方式將從以下內(nèi)容更改:
Image i = new Icon(someIcon, new Size(32, 32)).ToBitmap();
至
Image i = new Icon(someIcon, new Size(
(int)Math.Round(32.0*this.scaleFactor.Width),
(int)Math.Round(32.0*this.scaleFactor.Height))).ToBitmap();

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超8個(gè)贊
我知道有些麻煩,但是請(qǐng)考慮使用WPF重寫(xiě)您的應(yīng)用程序。WPF應(yīng)用程序在每個(gè)DPI設(shè)置上的外觀都相同。
- 3 回答
- 0 關(guān)注
- 668 瀏覽
添加回答
舉報(bào)