为什么Visual Studio会自动更改表单的布局?

我有一个Windows表单,其中包含3个文件:

  • AbcFrm.cs

  • AbcFrm.Designer.cs

  • AbcFrm.resx

每当我对datagridview的任何属性进行一些更改或添加新事件时,控件的大小会向右侧和底部变大,并导致某些控件超出范围。

我在执行次要属性更改之前和之后比较了.Designer.cs文件(例如,将datagridview的tabStop属性值从true更改为false),并发现在.Designer.cs文件中自动添加/更改了一些行/属性:

  • 一些控件’ .Size值的变化
  • 一些控件’ .Location值的变化
  • 一些控件’ .Padding值的变化
  • 表单的.AutoScaleDimensions变得更大
  • 表单的.ClientSize变得更大

编辑

我意识到当我将分辨率从150%更改为125%并重新打开应用程序时,控件又回到了正确的位置,因为窗体现在具有更大的缩放尺寸。 我的问题与这个问题类似

原因是代码可能已在具有不同分辨率的计算机中编辑。 然而,解决方案并不令人满意,因为它不能解决问题,只能找出原因。

我该如何防止这种情况发生? 我正在使用Visual Studio 2010,我的操作系统是Windows 10。

推理

这是由于AutoScaleMode属性,它根据不同开发机器之间的每英寸点数(DPI)的差异来缩放winforms中对象的大小和位置。 这是一个不能也不应该更改的function 。 有关官方文档,请参阅MSDN上的Windows窗体中的自动缩放 。

假设有两台机器,机器A和B.机器A有96 DPI,比例因子100%。 机器B具有144 DPI和150%比例因子作为其推荐设置。 在机器A中创建了WinForm,机器B正在尝试编辑该WinForm。

当机器B中的Visual Studio遇到机器B的DPI与用于创建WinForm的DPI不同时,它会自动缩放WinForm中的对象,以尝试使WinForm在机器B中显示为在机器A中的外观。 。 因此, 这会导致WinForm.Designer.cs文件中的某些属性自动更改

解决方法

为了在没有任何自动对齐的高DPI机器中继续编辑WinForms,我们需要在高DPI机器中设置DPI以匹配用于创建WinForm的机器中的DPI。 这可以通过将缩放系数调整为100%(96 DPI;右键单击桌面>显示设置)并重新启动Visual Studio(或重新登录到Windows,如果这不起作用)来完成。

注意:此处的关键是将DPI调整为用于创建WinForm的计算机的原始DPI 。 仅调整缩放系数可能不起作用 。 您可能需要使用屏幕分辨率。

问题可能在于Visual Studio 2010或Windows 10(取决于您如何看待它)。 在制作VS 2010的Windows 7之后,图形API发生了变化。 然后有正常的100%DPI scalling,没有别的。 也许你应该尝试安装Visual Studio 2015社区版 ,它应该解决这个问题。

编辑:

目前无法锁定WinForms编辑器更改设计器文件中的设置。 这实际上是预期的行为,因此定位/大小/缩放值会发生变化以调整当前显示设置,因此如果启用了自动缩放和DPI警报,则可以调整这些值。 以下是使用高DPI设置的一些好资源:

  • WinForms在大DPI设置下扩展 – 它是否可能?
  • 使用WinForms设计器时,是否始终需要将DPI设置为96?
  • 无法禁用Visual Studio 2012的DPI缩放
  • Visual Studio扩展和DPI感知

我的解决方案是添加注册表项LogPixels并重新启动计算机。 此密钥以前没有出现在我的机器上。

 [HKEY_CURRENT_USER\Control Panel\Desktop] "LogPixels"=dword:00000096 

我在Windows 10上使用高分辨率显示器。 我尝试将显示设置切换回100%,但没有效果。

这个注册表设置对我有用。

最近我自己遇到了这个问题,我花了一些时间在其他地方跟踪这些回复和其他资源。 我在Windows 10下使用VS 2015 Pro中的VSTO工具开发Excel Addin时遇到此问题。

在玩了不少之后,我创建了一个单一forms的Windows窗体解决方案,我可以用它来观察各种事物的影响,比如AutoScale属性等。我遇到了一些我认为真的很奇怪的东西:

在Excel Addin解决方案中,我在form.Load处理程序的第一行代码中设置了一个断点。 那时,我看到:

 Screen.PrimaryScreen.Bounds {X=0 Y=0 Width=5760 Height=3240} 

这很有趣,远远超出我系统的屏幕分辨率,即3840×2160。

我关闭此解决方案并立即打开单一forms的“测试”解决方案,该解决方案有一个窗体(窗体)只有2个标签,这些标签填充在带有Top / Left / Width / Height值的Load事件中,并且按钮的标题是为按钮本身做同样的事情。 没有任何其他代码。 在此解决方案中,运行在同一系统上,我看到:

 Screen.PrimaryScreen.Bounds {X=0 Y=0 Width=1920 Height=1080} 

为什么Windows / Visual Studio会在同一台计算机上报告不同的屏幕大小,并且绝对不会对任何类型的系统设置进行任何更改?

基本系统设置:

联想Yoga 920,屏幕分辨率= 3840 x 2160,缩放= 200%

同样,在Visual Studio中运行两个不同的解决方案之间根本没有进行任何更改。

任何提示或想法将是最受欢迎的!

总的来说,在我看来,MS在能够使用VS创建便携式解决方案方面确实填补了空白! 只是我的2c ….