WinForms多DPI,多个开发人员
本文关键字:开发 DPI WinForms | 更新日期: 2023-09-27 18:25:13
我正在与大量开发人员一起开发WinForms应用程序,他们有不同的屏幕配置,包括不同的DPI设置。因此,我们的应用程序可以缩放。我们已经使用AutoScaleMode = AutoScaleMode.Font
将所有表单设置为自动缩放,并根据表单开发的设置设置相应的AutoScaleDimensions
。
使用这些配置,WinForms可以在不同的屏幕上正确扩展,问题是,当具有不同屏幕配置的开发人员在设计器模式下打开窗体时,Visual Studio会通过实际修改自动生成的代码来扩展控件,以包含对象的"新"维度,并且还通过修改和CCD_ 3属性来匹配新监视器。
如果我没有几个开发人员在同一个表单上工作,这种行为是可以的。如果发生这种情况,并且这些开发人员有不同的屏幕配置,那么在使用VCS合并更改时会产生很多冲突,更不用说我会为不同的屏幕分辨率存储值,从而扰乱UI。
为了解决这个问题,我尝试通过设置AutoScaleMode = AutoScaleMode.None
并为控件实现自定义设计器来关闭自动缩放。此设计器仅以一种分辨率保存对象的大小,然后通过遮蔽Size
属性并根据当前DPI返回缩放值。我这样做只是为了发现VS设计器根据自定义设计器所说的生成代码,而不是实际存储在对象中的值。
那么,有人知道如何绕过这个问题吗?
看来我自己也找到了答案。
解决方案是创建一个自定义设计器,通过自定义设计器的ShadowedProperties
数组欺骗设计器,使其在显示表单时相信它正在接收缩放的值,但在生成代码时,通过以下代码示例中的解释,为其提供未缩放的值:
// This is the custom designer
public class ScalingDesigner : ControlDesigner
{
public ScalingDesigner(){};
// Say we want to correct the Size property
public Size Size
{
get
{
// When the serializer asks for the value, give him the shadowed one
return (Size)this.ShadowedProperties["Size"]
}
set
{
// When setting the value, assign the standard-DPI based value to the one the serializer would use
this.ShadowedProperties["Size"] = value;
// ... perform all the DPI scaling logic ...
// Then assign a scaled value to the displayed control
this.Control.Size = new Size(scaledWidth, scaledHeight)
}
}
// Associate the shadowed values
public override void PreFilterProperties(IDictionary properties)
{
base.PreFilterProperties(properties);
properties["Size"] =
TypeDescriptor.CreateProperty(
typeof(ScalingDesigner),
(PropertyDescriptor)properties["Size"],
new Attribute[0]);
}
}
// ... and on your control ...
[Designer(typeof(ScalingDesigner))]
public class MyControl : Control
{
// ... whatever logic you want to implement ...
}