FormBorderStyle在Fixed和Sizable之间的奇怪行为

时间:2009-05-13 01:32:13

标签: c# .net winforms border

我默认使用FormBorderStyle = FixedToolWindow创建了一个简单的测试表单,并添加了一个按钮,该按钮将在鼠标按下时在FixedToolWindow和SizableToolWindow之间切换。

在这两者之间切换FormBorderStyle似乎会产生一种奇怪的效果,这会导致我的应用程序出现很多问题。问题是窗口似乎改变了大小,我不能拥有它。我只想更改边框,我需要保持相同的表单大小。

例如,这是按钮代码:

private void button1_Click(object sender, System.EventArgs e) {
    if(FormBorderStyle == FormBorderStyle.FixedToolWindow) {
        System.Diagnostics.Debug.WriteLine("SWITCHING: FIXED -> SIZABLE");
        FormBorderStyle = FormBorderStyle.SizableToolWindow;
    } else {
        System.Diagnostics.Debug.WriteLine("SWITCHING: SIZABLE -> FIXED");
        FormBorderStyle = FormBorderStyle.FixedToolWindow;
    }
}

要调试我使用它:

private void Settings_SizeChanged(object sender, System.EventArgs e) {
    System.Diagnostics.Debug.WriteLine(this.Size);
}

这是按下开关按钮时的输出:

SWITCHING: FIXED -> SIZABLE
{Width=373, Height=169}
{Width=383, Height=179}
SWITCHING: SIZABLE -> FIXED
{Width=383, Height=179}
{Width=373, Height=169}

如何解决此问题?通过“修复”,我的意思是,如果可能的话,防止这种情况发生。我希望能够指定我的表单大小并保持这样,无论边框样式的类型如何。

此外,通过继承Form类的解决方案对我来说是完美的解决方案,以防任何人想要用这样的方法来解决这个问题。

修改
我做了一个小视频来演示这个问题。第一个测试显示表单大小实际上没有变化(视觉上),只有表单的位置稍有变化;但正如您在调试输出中看到的那样,Size属性的值会发生变化。您将在调试输出中看到第二个测试,即表单Size属性值更改,窗口大小本身也将更改。

请看这里:
http://screencast.com/t/0vT1vCoyx2u

4 个答案:

答案 0 :(得分:2)

您的问题是位置更改,而不是大小。此代码解决了视频中出现的问题。

        private void Form1_DoubleClick(object sender, EventArgs e)
        {
            Point _location = this.PointToScreen(this.ClientRectangle.Location);
            if (this.FormBorderStyle == FormBorderStyle.SizableToolWindow)
            {
                this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            }
            else
            {
                this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
            }
            Point _newloc = this.PointToScreen(this.ClientRectangle.Location);
            Size _diff = new Size(_newloc) - new Size(_location);
            this.Location -= _diff;
        }

在我看来,在这两种bordertyles之间切换时渲染表单移动的问题是DWM中的一个错误。

答案 1 :(得分:1)

我怀疑正在发生的事情是Windows窗体在边框大小改变时保持客户端大小(即内部区域)不变。这通常是一件好事,因为它确保窗口仍然可以正确地适合您放在其上的内容。

如果要保持相同的外部尺寸,可以在更改边框类型之前将尺寸保存到变量,然后将其恢复,从而解决此问题。不过,它们可能会略微闪烁。

答案 2 :(得分:0)

这对我来说很好:

    private Size _size;
    private void Form1_DoubleClick(object sender, EventArgs e)
    {
        _size = this.Size;
        if (this.FormBorderStyle == FormBorderStyle.SizableToolWindow)
        {
            this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
        }
        else
        {
            this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
        }
        this.Size = _size;
    }

答案 3 :(得分:0)

我有同样的问题。设置FormBorderStyle时客户端大小会更改,但它似乎不会立即放入clientrectangle属性。上面列出的代码几乎适合我,但不仅仅是存储大小,请确保存储客户端。当然,在上面的例子中,“this”可能是对客户端的引用 - 我不确定。无论如何,这对我有用:

_frmFilter.Height = 300 Dim _size As Size = .ClientSize _frmFilter.FormBorderStyle = FormBorderStyle.FixedToolWindow _frmFilter.ClientSize = _size

相关问题