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

Why does Visual Studio automatically changes the layout of my form?

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

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

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

编辑

我意识到,当我将分辨率从 150% 更改为 125% 并重新打开应用程序时,由于 windows 窗体现在具有更大的缩放比例,控件回到了正确的位置。我的问题类似to this question

原因是代码可能是在不同分辨率的电脑上编辑的。但是,解决方案并不令人满意,因为它没有解决问题,只是找出原因。

如何防止这种情况发生?我使用的是 Visual Studio 2010,我的 OS 是 Windows 10.

问题可能出在 Visual Studio 2010 年或 Windows 10 年(取决于您如何看待它)。图形 API 在 Windows 7 之后更改,其中 VS 2010 是为之制作的。然后有 100% DPI 缩放是正常的,没有别的。也许您应该尝试安装 Visual Studio 2015 Community Edition 来解决问题。

编辑:

Currently 无法阻止 WinForms 编辑器更改设计器文件中的设置。这实际上是预期的行为,因此 positioning/size/scaling 值会更改以调整当前显示设置,因此如果打开自动缩放和 DPI 感知,则可以调整这些值。这里有一些使用高 DPI 设置的好资源:

推理

这是由于 AutoScaleMode 属性 根据不同开发机器之间每英寸点数 (DPI) 的差异缩放 winforms 中对象的大小和位置。这是 MSDN 上 cannot and should not be changed. For official documentation, see Automatic Scaling in Windows Forms 的一项功能。

假设有两台机器,机器 A 和 B。机器 A 的 DPI 为 96,比例因子为 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。仅调整比例因子 可能不起作用 。您可能需要调整屏幕分辨率。

我的解决方案是添加注册表项 LogPixels 并重新启动机器。我的机器上以前没有这个密钥。

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

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

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

最近我自己 运行 遇到了这个问题,我花了一些时间在其他地方关注这些回复和其他资源。 我在 VS 2015 Pro 中使用 VSTO 工具开发 Excel 插件时遇到了这个问题,在 Windows 10.

玩了很久之后,我创建了一个 one-form Windows Forms 解决方案,我可以用它观察各种事物的效果,例如 AutoScale 属性等。 我已经 运行 进入了我认为真的很奇怪的东西:

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

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

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

我关闭这个解决方案并立即打开 single-form "test" 解决方案,它有一个表格(windows 表格)只有 2 个标签填写在 Load 具有 Top/Left/Width/Height 值的事件和一个标题相同的按钮,用于按钮本身。没有任何其他代码。在这个解决方案中,运行 在同一系统上,我看到:

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

为什么 Windows / Visual Studio 在同一台机器上报告不同的屏幕尺寸,而且完全没有对系统设置进行任何更改?

基本系统设置:

Lenovo Yoga 920, Screen resolution = 3840 x 2160, Scaling = 200%

同样,运行在 Visual Studio.

中的两个不同解决方案之间没有任何变化

欢迎任何提示或想法!

总的来说,在我看来,MS 在能够使用 VS 创建可移植解决方案方面确实做得很好!只是我的2c....

我在另一台具有其他 DPI 设置的计算机上编辑的程序遇到了同样的问题。我根据 this tutorial on DPI 找到的解决方法是在 Designer.vb 上找到以下行(在 vb 网络上工作)

    Me.AutoScaleDimensions = New System.Drawing.SizeF(8.0!, 16.0!)
    Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font

将它们注释掉,通过添加将自动缩放更改为 None:

    Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None

并重建并重新运行程序。控件又回到了原位。之后,我通过取消注释上面的代码将 AutoScaleDimensions 设置回原始值并将 AutoScaleMode 设置回 Font 并且一切正常。 WinForms 通过 它自己的缩放机制实现 DPI 缩放,该机制计算窗体设计所在的系统与它 运行 所在的系统之间的缩放差异。(如所述在前面提到的 tutorial) 中。我看到上面的解决方法重置了创建表单的机器的比例因子。