如何使紧凑的框架自定义控件AutoScale感知
本文关键字:自定义控件 AutoScale 感知 框架 何使紧 | 更新日期: 2023-09-27 18:14:44
Windows Forms(包括我正在使用的Windows Forms for Compact framework)有一个自动缩放功能。通过将AutoScaleMode
属性设置为AutoScaleMode.Dpi
,您为320x200设计的应用程序会自动缩放到更大的显示器,例如VGA设备。
这工作得很好,但我有一些自制的自定义控件,做自己的OnPaint
的东西,我希望他们的规模以及。不幸的是,我没有找到关于如何做到这一点的好的文档或示例。
当前,我正在这样做:
protected SizeF zoom = new SizeF(1.0, 1.0);
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
zoom = factor; // remember the zoom factor
}
protected override void OnPaint(PaintEventArgs e)
{
// scale everything by zoom.Width and zoom.Height
...
e.Graphics.DrawImage(...);
...
}
它工作,但我想知道这是否是"正确的方式"去做。由于(根据ILSpy)没有其他CF控件有一个内部字段来存储比例因子,我想知道是否有一个更容易或更好的方法来做到这一点。
我们通常在控件和窗体中处理OnResize
中的所有缩放。我们还必须支持许多具有疯狂尺寸和DPI的不同设备(有些平台甚至无法报告正确的DPI!)我们发现关闭AutoScaleMode
后,您可以按比例使用这样的帮助器来缩放OnResize
中的窗体子窗体。您只需在构造函数中将Size _initalSize
成员集添加到表单大小。然而,我通常发现在大多数表单上,我必须编写自定义布局代码来适当地处理纵向和横向显示。
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
// Scale the control
ScaleChildren(this, ref _initialFormSize);
}
public static void ScaleChildren(Control control, ref Size initialSize, float fontFactor)
{
if (control == null || control.Size == initialSize)
return;
SizeF scaleFactor = new SizeF((float)control.Width / (float)initialSize.Width, (float)control.Height / (float)initialSize.Height);
initialSize = control.Size;
if (!float.IsInfinity(scaleFactor.Width) || !float.IsInfinity(scaleFactor.Height))
{
foreach (Control child in control.Controls)
{
child.Scale(scaleFactor);
if (child is Panel)
continue;
try
{
// scale the font
float scaledFontSize = (float)(int)(child.Font.Size * scaleFactor.Height * fontFactor + 0.5f);
System.Diagnostics.Debug.WriteLine(
string.Format("ScaleChildren(): scaleFactor = ({0}, {1}); fontFactor = {2}; scaledFontSize = {3}; '"{4}'"",
scaleFactor.Width, scaleFactor.Height, fontFactor, scaledFontSize, child.Text));
child.Font = new Font(child.Font.Name, scaledFontSize, child.Font.Style);
}
catch { }
}
}
}