Deeply nested controls do not resize properly when their parents are resized

Article ID: 953934
Expand all | Collapse all
Source: Microsoft Support

RAPID PUBLISHING

RAPID PUBLISHING ARTICLES PROVIDE INFORMATION DIRECTLY FROM WITHIN THE MICROSOFT SUPPORT ORGANIZATION. THE INFORMATION CONTAINED HEREIN IS CREATED IN RESPONSE TO EMERGING OR UNIQUE TOPICS, OR IS INTENDED SUPPLEMENT OTHER KNOWLEDGE BASE INFORMATION.

Action

A parent control is resized in an application with deeply-nested, docked controls.

Result

The nested controls do not resize or dock properly.

Cause



In .NET applications, docked controls sometimes do not resize when their parents are resized if they are deeply nested.  This problem occurs on both 64-bit and on 32-bit platforms, but requires a deeper nesting level on 32-bit systems.


What happens is that when the top level control lays out, SetBoundsCore calls SetWindowPos to resize the child controls. Each child control receives a WM_WINDOWPOSCHANGED notification, which triggers a layout event, which calls SetBoundsCore, which calls SetWindowPos.  Each call to SetWindowPos goes into kernel mode and then back out to deliver the WM_WINDOWPOSCHANGED notification. Eventually the thread runs out of kernel stack space and SetWindowPos fails silently.

Resolution



To work around this problem, override the nested container (often a Panel or GroupBox) control's OnSizeChanged event as shown below and use this custom implementation of the Panel or GroupBox instead of the default .Net Panel control.

Visual C#

1) Add a new class named MyPanel to the project

2) Use the following code in the MyPanel Class

public class MyPanel : Panel

{

    protected override void OnSizeChanged(EventArgs e)

    {

        if (this.Handle != null)

        {

            this.BeginInvoke((MethodInvoker)delegate

            {

                base.OnSizeChanged(e);

            });

        }

    }

}





3) Build the project and use the MyPanel component from the ToolBox

Visual Basic

1) Add a new class named MyPanel to the project

2) Use the following code in the MyPanel Class

 

Public Class MyPanel

    Inherits Panel

 

    Public Delegate Sub SizeChangedDelegate(ByVal e As EventArgs)

 

    Private Sub SizeChangedDelegateHandler(ByVal e As EventArgs)

        MyBase.OnSizeChanged(e)

    End Sub

 

    Protected Overrides Sub OnSizeChanged(ByVal e As EventArgs)

        If Me.Handle.ToInt32 > 0 Then

 

            Dim obj(0) As Object

            obj(0) = e

 

            Dim scd As New SizeChangedDelegate(AddressOf SizeChangedDelegateHandler)

            Me.BeginInvoke(scd, obj)

        End If

    End Sub

 

 

End Class

 



3) Build the project and use the MyPanel component from the ToolBox



Note
The asynchronous BeginInvoke call will introduce a small delay, so have only some of the nested Panels derive from MyPanel.

DISCLAIMER

MICROSOFT AND/OR ITS SUPPLIERS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY, RELIABILITY OR ACCURACY OF THE INFORMATION CONTAINED IN THE DOCUMENTS AND RELATED GRAPHICS PUBLISHED ON THIS WEBSITE (THE “MATERIALS”) FOR ANY PURPOSE. THE MATERIALS MAY INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS AND MAY BE REVISED AT ANY TIME WITHOUT NOTICE.

TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND/OR ITS SUPPLIERS DISCLAIM AND EXCLUDE ALL REPRESENTATIONS, WARRANTIES, AND CONDITIONS WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO REPRESENTATIONS, WARRANTIES, OR CONDITIONS OF TITLE, NON INFRINGEMENT, SATISFACTORY CONDITION OR QUALITY, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE MATERIALS.

Properties

Article ID: 953934 - Last Review: June 3, 2008 - Revision: 1.0
Keywords: 
kbnomt kbrapidpub KB953934

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com