切换到VS 2012,现在表格没有正确调整大小?

时间:2013-04-12 22:44:36

标签: c# winforms visual-studio-2010 visual-studio-2012

我昨天从VS 2010切换到了VS 2012,除了这个以外,一切似乎都很顺利。

我的表单上有一个按钮,按下时会扩展表单的宽度以显示其他控件。再次按下按钮,它会减小宽度以隐藏这些控件。现在所有这些在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 = ">>";

    }

1 个答案:

答案 0 :(得分:12)

很长一段时间,表单的宽度不是188像素。现在有了VS2012,Windows终于不再撒谎了。

问题是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);
}

将此代码中的someControl替换为控件的名称。