2014-10-01 124 views
0

我正在开发一个WinForms应用程序以及大量开发人员,他们拥有不同的屏幕配置,其中包括不同的DPI设置。因此,我们的应用程序可以扩展我们设置的所有窗体,使用AutoScaleMode = AutoScaleMode.Font自动缩放,并设置相应的AutoScaleDimensions,具体取决于开发窗体的设置。WinForms多个DPI,多个开发人员

利用这些构造的WinForms适当缩放跨不同的屏幕,问题是,当用不同屏结构的显影剂打开在设计者模式的形式,Visual Studio中通过实际修改自动生成的代码包含缩放控制对象的“新”尺寸,以及修改和AutoScaleDimensions属性以匹配新的监视器。

如果我没有几个开发人员在同一个表单上工作,这种行为是可以的。如果发生这种情况,并且这些开发人员拥有不同的屏幕配置,那么在使用我们的VCS合并这些更改时会产生大量冲突,而不是说我将为不同的屏幕分辨率存储值,从而搞乱了用户界面。

为了解决这个问题,我尝试通过设置AutoScaleMode = AutoScaleMode.None并为我的控件实现自定义设计器来关闭自动缩放功能。这位设计师只将对象的尺寸保存在一个分辨率中,然后通过隐藏Size属性并根据当前DPI返回缩放值。我这样做只是为了发现VS设计人员根据定制设计人员所说的生成代码,而不是实际存储在对象中的值。

那么,有没有人知道如何解决这个问题?

+0

'AutoScaleMode = AutoScaleMode.Dpi' [MSDN](http://msdn.microsoft.com/en-us/library/system.windows.forms。 autoscalemode(v = vs.110).aspx) – bansi 2014-10-01 03:43:04

+0

@bansi你可以这样做,它会导致相同的行为。设计人员将修改自动生成的代码上的值以匹配新的DPI .. – cgledezma 2014-10-01 03:45:38

+0

在提交时忽略一些自动生成的代码块(如果您的VCS可以这样做)? – 2014-10-01 09:53:17

回答

0

好吧,好像我自己找到了答案。

解决方案是创建一个自定义设计器,让设计师相信它在显示表单时会收到一个缩放值,但是当生成代码给他的非缩放值时,通过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 ... 
}