views:

310

answers:

4

Hi,

Working with winforms I wonder if there is some way to prevent vertically resize of the form. I would like to allow user to resize form in all directions except vertically.Moreover I would like to allow vertically resize in upward direction, but not downward.

I have tried to use maximumsize by setting it to: Me.maximumsize = new size(0,me.height)

I set width to 0 because I want to allow user to change form width.

Unfortunately it doesn't work.

Any ideas?

+1  A: 

There are several solutions. An easy one is this:

Dim originalSize As Integer = Me.Height

Private Sub Form1_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
    If Me.Height <> originalSize Then
        Me.Height = originalSize
    End If
End Sub

Have in mind that resizes are always down, when you resize up what you are doing is to change the location of the form and resizing down.

SoMoS
Good idea to check whether the height needs to be modified or not because the Height change will cause another Resize event to be fired, and so on. Without the `if`, you would be stuck in an infinite loop.
Tiberiu Ana
Good solution but in my case the only problem is that I'll have to update constantly originalSize variable in different points and it's not quite comfortable for me. But your solution is good! thanks
You can just create a custom property that updates the size of the form and also updates the originalSize variable at the same time.
SoMoS
A: 

Register for Control.Resize Event and enforce your desired height.

KMan
+1  A: 

Set form's Maximum & Minimum Size properties or write the code below at Form_Load:

this.MaximumSize=new System.Drawing.Size(2048, 300);
this.MinimumSize=new System.Drawing.Size(0, 300);

Give same height to both.

HasanGursoy
+2  A: 

You have to be careful to allow the form to resize itself at startup. Necessary to accommodate scaling needed on a machine that has a different video DPI setting or a different system font size. Or a user override that changed the height of the title bar. All of this is sorted out by the time the Load event runs. Thus:

protected override void OnLoad(EventArgs e) {
  Screen scr = Screen.FromControl(this);
  this.MinimumSize = new Size(this.MinimumSize.Width, this.Height);
  this.MaximumSize = new Size(scr.WorkingArea.Width, this.Height);
}

The next thing you ought to do is fix the behavior of the cursor when the user moves it on an edge of the window that allows resizing the window vertically. That's a bit ugly, you have to trap the WM_NCHITTEST message with WndProc and change the message return value:

protected override void WndProc(ref Message m) {
  base.WndProc(ref m);
  if (m.Msg == 0x84) {  // Trap WM_NCHITTEST
    switch (m.Result.ToInt32()) {
      case 12: m.Result = (IntPtr)2; break;  // HTTOP to HTCAPTION
      case 13: m.Result = (IntPtr)10; break; // etc..
      case 14: m.Result = (IntPtr)11; break;
      case 15: m.Result = (IntPtr)1; break;
      case 16: m.Result = (IntPtr)10; break;
      case 17: m.Result = (IntPtr)11; break;
    }
  }
}
Hans Passant
Excellent sample!this is just what I want. Here there are some other good solutions but I think this is the one that fits best my needs. With this I can take full control over all resizing directions. Great code snippet! But one thing, I have a doubt... I wonder If I can change message return values to the values I want. Is it important the message values you return or not? Can you return any ones? Why do you return these values and not others?Thanks very much!
Review the MSDN docs for WM_NCHITTEST. http://msdn.microsoft.com/en-us/library/ms645618%28VS.85%29.aspx
Hans Passant