Strange behavior in FormBorderStyle between fixed and meaningful
I created a simple test form with FormBorderStyle = FixedToolWindow by default and added a button that will toggle between FixedToolWindow and SizableToolWindow on mouse click.
Switching the FormBorderStyle between these two seems to create a strange effect causing a lot of problems in my application. The problem is that the window seems to be resizing and I can't seem to do it. I just want to change the border, I need the size of the form to stay the same.
For example, 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 for debugging, I use this:
private void Settings_SizeChanged(object sender, System.EventArgs e) {
System.Diagnostics.Debug.WriteLine(this.Size);
}
And here is the output when I click the radio 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 "fix", I mean, prevent this if possible. I want to be able to specify the size of my form and stay that way regardless of the type of border style.
Also, a solution by subclassing the Form class would be a perfect solution for me if anyone would like any ideas for solving this problem with a method like this.
EDIT:
I made a small video to demonstrate the problem. The first test shows that the size of the form does not actually change (visually), only the position of the form changes slightly; but the values for the Size property change as you can see in the debug output. The second test, which you will see in the debug output, change the values of the form property and resize the window.
Please see here:
http://screencast.com/t/0vT1vCoyx2u
a source to share
Your problem is with the location change, 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 seems to me that the problem with the rendered form moving when switching between these two border styles is a bug in DWM.
a source to share
I suspect what is happening is that Windows Forms keeps the client size (i.e. the inner area) the same when the border is resized. This is generally a good thing, because it ensures that the window will still properly fit the content you have overlaid on it.
If you want to keep the same outer dimensions, you can work around it by storing the size to a variable before changing the border type and then restoring it. They will probably flicker slightly.
a source to share
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;
}
a source to share
I had the same problem. The client resizes when you set the FormBorderStyle, but it doesn't seem to immediately hit the clientrectangle property. The above code almost worked for me, but instead of storing the size, remember to save clients. Of course, in the example above, maybe "this" was a client reference - I wasn't sure. Buy anyway, this worked for me:
_frmFilter.Height = 300 Dim _size As Size = .ClientSize _frmFilter.FormBorderStyle = FormBorderStyle.FixedToolWindow _frmFilter.ClientSize = _size
a source to share