我的表单上有一个按钮,按下该按钮可以扩展表单的宽度以显示其他控件.再次按下按钮,它会减小宽度以隐藏这些控件.现在所有这些在VS 2010中运行良好,并且在我在VS 2012中调试时工作正常但是一旦我发布或编译项目并在单击按钮时打开.exe,它就会增加5到宽度而不是它需要100.我再次点击它然后它会像它应该更改为372并显示我的所有控件.我再次点击它来隐藏控件,它部分隐藏了控件(转到188神秘的5)我希望所有这一切都有意义,我希望有更好的方法来运行我需要的过程.
以下是我目前正在使用的代码,从2010年到2012年,我没有改变任何内容.实际上,如果我在2010年打开这个相同的解决方案并发布一切正常.
private void button1_Click(object sender,EventArgs e) { if (this.Width == 188) { this.Width = 372; this.Height = 540; progressBar.Value = 100; copied_status.Text = ("Output View Enabled"); } else { progressBar.Value = 100; copied_status.Text = ("Output View Disabled"); this.Width = 188; this.Height = 540; } if (this.Width == 372) { button1.Text = "<<"; } else button1.Text = ">>"; }
解决方法
问题是Aero中的胖窗口边框.在Vista中引入该功能时,它们是一个极端的appcompat问题.非常必要,因为这两个像素很难用鼠标击中.但是与应用程序创建窗口的方式完全不兼容.它要求CreateWindow()函数的特定窗口大小,外部大小,nWidth和nHeight参数.但真正重要的是客户区的大小,边框内窗口的一部分.如果微软不会对此做些什么,那么旧的应用程序最终会导致客户区域太小.看起来非常糟糕,窗口内容不再适合.例如,不能完全显示对表格底部或右侧的控制.
所以,偷偷摸摸地,Aero通过额外的胖边界宽度使窗户更大.当应用程序询问窗口大小时,它偷偷地说它的宽度相同.该应用程序不知道它仍然运行与XP上相同的窗口大小.这很好用,但并不完全理想.例如,很难让窗口边缘与该谎言正确对齐.
Aero是否会对窗口大小产生影响取决于EXE标头中记录的目标操作系统.当它看到早于6.00的版本(Vista版本号)时,它将假设您的EXE是遗留程序,不知道胖边界功能.所以需要撒谎.您已经将目标版本号设置为4.00很长一段时间运行,它是由.NET编译器在构建程序时编写的.您可以使用dumpbin.exe / headers yourapp.exe查看它.
这最终在VS2012和.NET 4.5中发生了变化.哪个是XP版本不可用的.NET版本.编译器最终可以认真地假设XP是历史记录,并且您将在支持Aero的Windows版本上运行.因此,它将EXE标头中的目标Windows版本设置为6.00.相应地,Aero现在将停止躺在窗口大小.你得到的是真实的,而不是假的.
因此,快速解决方法是将目标.NET框架版本更改为4.0.这在XP上可用,所以你会再次撒谎.
当然最好修复你的代码.永远不要使用尺寸,宽度或高度属性,它们将不可避免地取决于边框和标题大小.请使用ClientSize属性,这是稳定的属性和您真正关心的属性.但是要小心这个属性,当一个窗体在其视频适配器设置为每英寸超过96个点的机器上运行时,它可能会重新缩放.另一个在Vista及以上版本中非常容易使用的功能.重新缩放会根据DPI设置按比例更改ClientSize.
真正的解决方法是使用bool字段来跟踪窗口状态.并根据要隐藏或显示的控件的位置设置ClientSize属性.粗略地说:
private bool enlarged; private void button1_Click(object sender,EventArgs e) { enlarged = !enlarged; int width = someControl.Left - 5; if (enlarged) width = someControl.Right + 5; this.ClientSize = new Size(width,this.ClientSize.Height); }