Suk*_*wal 33 fonts dpi winforms
我为小型企业创建了一个应用程序.办公室的一些员工无法正确查看表格.原因是他们的DPI设置设置为96dpi以上.有人知道控制这个的方法吗?
对于有winforms应用程序经验的所有人,如何控制表单布局以使DPI不影响应用程序的外观?
Ian*_*oyd 63
假设您没有尝试兑现用户的UI字体选择(SystemFonts.IconTitleFont),并且只对一种字体大小的表单进行硬编码(例如Tahoma 8pt,Microsoft Sans Serif 8.25pt),您可以将表单设置AutoScaleMode为ScaleMode.Dpi.
这将通过调用按比例缩放表单的大小和大部分子控件,后者依次对自身和所有子控件进行recursivly 调用.将根据新缩放因子的需要增加控件的位置,大小,字体等.CurrentDpiSetting / 96Form.Scale()ScaleControl()ScaleControl
警告:并非所有控件都能正确缩放.例如,列表视图的列不会随着字体变大而变宽.为了处理这个问题,您必须根据需要手动执行其他扩展.我这样做是通过覆盖受保护的
ScaleControl()方法,并手动缩放listview列:Run Code Online (Sandbox Code Playgroud)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); } } }
如果您只是使用控件,这一切都很好.但是,如果您使用任何硬编码像素大小,则需要根据表单的当前比例因子缩放像素宽度和长度.可能具有硬编码像素大小的情况的一些示例:
如果是这种情况,您需要通过" 当前比例因子 " 来缩放这些硬编码值.不幸的是,没有提供"当前"比例因子,我们需要自己记录.解决方案是假设最初缩放因子为1.0并且每次ScaleControl()调用时,通过新因子修改运行比例因子.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
最初缩放因子是1.0.如果然后缩放形式1.25,则缩放因子变为:
1.00 * 1.25 = 1.25 //scaling current factor by 125%
Run Code Online (Sandbox Code Playgroud)
如果然后缩放表单0.95,则新的缩放因子变为
1.25 * 0.95 = 1.1875 //scaling current factor by 95%
Run Code Online (Sandbox Code Playgroud)
使用a的原因SizeF(而不是单个浮点值)是缩放量在x和y方向上可以不同.如果将表单设置为ScaleMode.Font,则表单将缩放为新的字体大小.字体可以具有不同的宽高比(例如, Segoe UI比Tahoma更高的字体).这意味着您必须独立缩放x和y值.
因此,如果您想将控件放在位置(11,56),则必须更改定位代码:
Point pt = new Point(11, 56);
control1.Location = pt;
Run Code Online (Sandbox Code Playgroud)
至
Point pt = new Point(
(int)Math.Round(11.0*this.scaleFactor.Width),
(int)Math.Round(56.0*this.scaleFactor.Height));
control1.Location = pt;
Run Code Online (Sandbox Code Playgroud)
如果您要选择字体大小,则同样适用:
Font f = new Font("Segoe UI", 8, GraphicsUnit.Point);
Run Code Online (Sandbox Code Playgroud)
必须成为:
Font f = new Font("Segoe UI", 8.0*this.scaleFactor.Width, GraphicsUnit.Point);
Run Code Online (Sandbox Code Playgroud)
并将32x32图标提取到位图将改为:
Image i = new Icon(someIcon, new Size(32, 32)).ToBitmap();
Run Code Online (Sandbox Code Playgroud)
至
Image i = new Icon(someIcon, new Size(
(int)Math.Round(32.0*this.scaleFactor.Width),
(int)Math.Round(32.0*this.scaleFactor.Height))).ToBitmap();
Run Code Online (Sandbox Code Playgroud)
等等
支持非标准DPI显示是所有开发人员应支付的税.但事实上,没有人愿意为什么微软放弃并增加了Vista的能力,使显卡能够扩展任何不能正确处理高dpi的应用程序.
Nic*_*ick 16
通过全局搜索/替换将AutoScaleMode设置为在任何地方继承(即所有UserControl),然后在主窗体上将AutoScaleMode设置为Dpi.
我还发现布局容器比这种情况下的锚更好.
| 归档时间: |
|
| 查看次数: |
27189 次 |
| 最近记录: |