Simonetos Simonetos - 6 months ago 39
Vb.net Question

VB.NET - How to add borders on an MDI child borderless form?

I am using this way below, to add borders to all my MDI child borderless forms...

Private Sub Form_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
If Me.WindowState = FormWindowState.Maximized Then
Me.Padding = New Padding(0, 0, 0, 0)
Me.BackColor = Color.FromArgb(76, 76, 76)
Else
Dim MF_Rect As New Rectangle(5, 5, Me.ClientSize.Width, Me.ClientSize.Height)
Dim MF_Color = New SolidBrush(Color.FromArgb(76, 76, 76))
e.Graphics.FillRectangle(MF_Color, MF_Rect)
Me.Padding = New Padding(5, 5, 5, 5)
Me.BackColor = Color.FromArgb(64, 64, 64)
End If
End Sub


But, if MDI child form steps out of MDI parent's borders, even half of it, and then maximize and normalize again, borders are gone!!! If I slide it in, I see them again!!!

Any idea why is this happening?

Answer

The dragging of the form outside of the MDI parent's borders is actually not required to reproduce the behavior. All you need to do is maximize and then normalize the form.

The problem is that the form is not being repainted after it has been resized. This is the default behavior, and it makes some degree of sense—the portion of the client area that is visible has always been visible, and therefore is still (presumably) painted correctly. As an optimization, then, no repaint is performed.

But this behavior doesn't work for you, because your painting logic is tied to the current size of the form. If the form changes its size, you want to repaint so that you can calculate new painting dimensions.

You can hack it by forcing an invalidation (and therefore a repaint) of the client area in response to a resize event. The Invalidate member function will do this.

But there is a better solution that causes this to happen automatically. Set the form's ResizeRedraw property to true. You can do this either from the designer (in the Properties window) or in the form class constructor. (Note that this is completely equivalent to calling the SetStyle member function and specifying the ControlStyles.ResizeRedraw flag.)

An even better approach would be to separate your painting of the borders (which logically are in the non-client area) from your painting of the contents of the form (which is the logical client area). I won't go into how to do that in this answer, but you can find a discussion and various tutorials elsewhere online. For example, Drawing Custom Borders in Windows Forms. This article is actually part of a larger library that implements this effect for you. Not sure how/if that library will work with MDI children. The MDI effect has been deprecated for many years…