简介:有很多评论说“WinForms 不能很好地自动缩放到 DPI/字体设置;切换到 WPF。”但是,我认为这是基于 .NET 1.1;看起来他们实际上在 .NET 2.0 中实现自动缩放方面做得很好。至少基于我们迄今为止的研究和测试。但是,如果你们中的一些人知道得更好,我们很乐意听取您的意见。 (请不要争论我们应该切换到 WPF ......现在这不是一个选择。)
问题:
到目前为止,我们已经确定的设计指南:
见 community wiki answer下面。
其中有哪些是不正确的或不充分的?我们应该采用任何其他准则吗?还有其他需要避免的模式吗?对此的任何其他指导将不胜感激。
最佳答案
不支持正确缩放的控件:
Label
与 AutoSize = False
和 Font
继承的。显式设置 Font
在控件上,因此它在“属性”窗口中以粗体显示。 ListView
列宽不缩放。覆盖表单的 ScaleControl
改为这样做。见 this answer SplitContainer
的 Panel1MinSize
, Panel2MinSize
和 SplitterDistance
属性(property)TextBox
与 MultiLine = True
和 Font
继承的。显式设置 Font
在控件上,因此它在“属性”窗口中以粗体显示。 ToolStripButton
的形象。在表单的构造函数中:ToolStrip.AutoSize = False
ToolStrip.ImageScalingSize
根据 CreateGraphics.DpiX
和 .DpiY
ToolStrip.AutoSize = True
如果需要。 有时
AutoSize
可以留在True
但有时它无法在没有这些步骤的情况下调整大小。使用 .NET Framework 4.5.2 无需更改即可工作和 EnableWindowsFormsHighDpiAutoResizing
. TreeView
的图像。套装ImageList.ImageSize
根据 CreateGraphics.DpiX
和 .DpiY
.对于 StateImageList
, 无需更改 .NET Framework 4.5.1和 EnableWindowsFormsHighDpiAutoResizing
. Form
的大小。比例尺固定Form
创建后手动。 设计指南:
AutoScaleMode = Font
.(字体将处理 DPI 更改和系统字体更改
尺寸设置; DPI 将只处理 DPI 更改,而不处理对
系统字体大小设置。)
AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
,假设 96dpi(请参阅下一个项目符号)和 MS Sans Serif 的默认字体(请参阅第二个项目符号)。这是设计师自动添加的根据您打开设计器的 DPI...
我们许多最古老的设计师文件。也许 Visual Studio .NET(
VS 2005 之前的版本)没有正确添加。
120dpi;但互联网上的智慧说坚持96dpi;
实验在那里;按照设计,这无关紧要,因为它只是更改了
AutoScaleDimensions
设计者插入的行)。要将 Visual Studio 设置为在高分辨率显示器上以虚拟 96dpi 运行,
找到它的 .exe 文件,右键单击以编辑属性,然后在兼容性下
选择“覆盖高 DPI 缩放行为。缩放执行者:系统”。
如果您想要除 MS Sans Serif 之外的应用程序范围的默认字体,请在最基础 Form 的构造函数中使用叶控件或。 (在容器上设置字体似乎关闭
该容器的自动缩放,因为它按字母顺序出现在 AutoScaleMode 和 AutoScaleDimensions 设置之后。)请注意,如果您确实更改了最基础 Form 的构造函数中的 Font,这将导致您的 AutoScaleDimensions 的计算方式与 6x13 不同;特别是,如果您更改为 Segoe UI(Win 10 默认字体),那么它将是 7x15……您需要触摸设计器中的每个表单,以便它可以重新计算该 .designer 文件中的所有尺寸,包括
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
. Right
或 Bottom
anchor 定到一个用户控件......它的定位不会自动缩放;相反,放下面板或其他
容器到您的 UserControl 并将您的其他控件 anchor 定到
该小组;让面板使用 Dock
Right
, Bottom
, 或 Fill
在你的用户控件。
ResumeLayout
时,只有控件列表中的控件最后的
InitializeComponent
被调用将自动缩放...如果你动态添加控件,则需要
SuspendLayout();
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ResumeLayout();
在你添加它之前在那个控件上。和你的如果您不使用 Dock,也需要调整定位
模式或布局管理器,如
FlowLayoutPanel
或 TableLayoutPanel
. ContainerControl
的基类应该离开 AutoScaleMode
设置为 Inherit
(在类 ContainerControl
中设置的默认值;但不是设计者设置的默认值)。如果您将其设置为其他任何内容,然后您的派生类尝试将其设置为 Font(应该如此),那么将其设置为 Font
的行为将清除AutoScaleDimensions
的设计师设置,导致实际上关闭自动缩放! (本指南与之前的指南相结合意味着您永远无法在设计器中实例化基类……所有类都需要设计为基类或叶类!)Form.MaxSize
静态/在设计器中。 MinSize
和 MaxSize
表格上的缩放比例不如其他所有内容。因此,如果您在 96dpi 中完成所有工作,那么在更高 DPI 时您的 MinSize
不会引起问题,但可能没有您预期的那么严格,但是您的 MaxSize
可能会限制您的 Size 的缩放,这可能会导致问题。如果你想要 MinSize == Size == MaxSize
, 不要在 Designer 中这样做...在你的构造函数或 OnLoad
中这样做覆盖...设置两者 MinSize
和 MaxSize
到您适当缩放的尺寸。 Panel
上的所有控件或 Container
应该使用 anchor 定或对接。如果你混合它们,自动缩放由 Panel
完成经常会以微妙的奇怪方式行为不端。 关于c# - 如何编写自动缩放到系统字体和 dpi 设置的 WinForms 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22735174/