views:

483

answers:

3

I have created a simple test form with FormBorderStyle = FixedToolWindow by default and added a button that will switch between FixedToolWindow and SizableToolWindow on mouse press.

Switching the FormBorderStyle between these two seems to produce a weird effect that's causing a lot of issues on my application. The problem is that the window seems to change size and I can't have that. I just want to change the border, I need the form size to remain the same.

For instance, here's the button code:

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;
    }
}

And to debug I use this:

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

And here's the output when I press the switch button:

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

How can I fix this behavior? And by "fix", I mean, prevent this from happening if possible. I want to be able to specify my form size and to remain like that, no matter the type of border style.

Also, a solution by subclassing the Form class would be the perfect solution for me in case anyone as any ideas to solve this problem with such a method.

EDIT:
I made a little video to demonstrate the problem. The first test shows that the form size doesn't actually change (visually), only the location of the form changes a little bit; but the values for the Size property do change, as you can see on the debug output. The second test you will see on the debug output that the form Size property values change and the window size itself will also change.

Please look here:
http://screencast.com/t/0vT1vCoyx2u

+1  A: 

I suspect what's happening is that Windows Forms is keeping the client size (i.e. inner area) the same while the border size changes. This is generally a good thing because it ensures that the window can still correctly fit the content that you've put on it.

If you want to maintain the same outer dimensions, you could work around it by saving the size to a variable before changing the border type, and then restoring it back. They'll probably a slight flicker, though.

Joe Albahari
Didn't work, it will actually make it worse. :/
Nazgulled
A: 

This worked fine for me:

    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;
    }
pyrochild
It doesn't, the form size still changes...
Nazgulled
If this solution and albahari's don't work, there's something you're not telling us about your requirements.
pyrochild
How would I be hiding something if I'm looking for help? All I can say is that that solution doesn't work, the window size still changes when I press the button...
Nazgulled
That "How" should actually be "Why".
Nazgulled
Not "hiding," just forgetting to include something. Like the fact that the issue only appears on Vista ;)
pyrochild
It happens, I can't remember anything can I? That and the fact that I didn't know this was a Vista specific issue, until I decided to test it on XP.
Nazgulled
Take a chill pill, bro. See the wink? See it? It indicates a jocular attitude -- I can't reasonably expect you to know it's Vista-specific any more than I can expect you to test on Ubuntu, Fedora, .NET CF, and Windows 7 build 7190. The sarcastic attitude will get you nowhere.
pyrochild
+1  A: 

Your issue is with the Location changing, not the Size. This code solves the problem seen in the video.

        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;
        }

It appears to me that the issue of the rendered form moving when switching between those two borderstyles is a bug in the DWM.

pyrochild
Thanks but this doesn't actually help me solve my whole issue. That's why I created the other question, cause it's more related. Please check the comment I left there if you are interested. I'll mark this answer as the right one (for this question of course) if I think it applies in the future. It's not relevant anymore in the time being.
Nazgulled
Can you elaborate as to what this *doesn't* solve, rather than just ignoring this question and only paying attention to your new one? (Never rewrite from scratch when you can refactor!)Refactor this discussion - don't rewrite it.
pyrochild
No, I can't. Sorry. If you don't want to help me in the other question, fine. It's your choice, but this question is no longer relevant and I'm not going to come back here. Thanks for all your help.
Nazgulled