Windows窗体(包括用于Compact Framwork的Windows窗体,我正在使用的)具有AutoScale feature。通过将AutoScaleMode
property设置为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控件都没有内部字段来存储比例因子,我想知道是否有更简单或更好的方法来执行此操作。
答案 0 :(得分:3)
我们通常在控件和表单中处理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 { }
}
}
}