Repost: Controls are unreachable after scroll and form resize.

G

Guest

Hopefully my subscription issues are now resolved. Here is my previous
posting:

I am developing a Windows Forms application using Visual Studio 2003 and C#.
The application uses the MDI style. The problem I have encountered appears
to be a bug in .NET Framework 1.1.

The problem is that controls in a panel on an MDI child form become
unreachable (no longer visible) if a combination of scroll, form hide, form
resize, and form show operations are performed.

The steps to create the problem are as follows:
- Show the child form in its normal location and size on the main form.
- Significantly resize the child form, causing scroll bars to appear.
- Scroll the child form visible area to the lower-right corner, causing
contained controls in the upper-left to no longer be visible.
- Hide the child form ( Form.Hide() ).
- Programmatically resize the child form to its original size.
- Show the the child form ( Form.Show() ).
- Now the only visible controls are the lower-right ones that were visible
after the above scroll operation and they are located in the upper-left
corner of the form.

I have recreated the problem with a very simple MDI example. I created a
main form set be an MDI container and added a single child form. The child
form contains a single panel which contains four Label controls and four
TextBox controls. The child form has the AutoScroll property set to true.
The panel has its AutoScroll property set to true and its Dock property set
to DockStyle.Fill. The Labels and TextBoxes are spread out on the panel and
form to the four corners. I added a couple of menu items to the main form to
hide and show the child form.

The sample code is provided below.

Is this a known problem?
Is there a work-around?

Thanks,
Dave

==== Sample Code ====

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace Main
{
public class MdiMain : System.Windows.Forms.Form
{
private System.Windows.Forms.MainMenu mainMenu;
private System.Windows.Forms.MenuItem mniTopFile;
private System.Windows.Forms.MenuItem mniExit;
private System.Windows.Forms.MenuItem mniTopActions;
private System.Windows.Forms.MenuItem mniOpen;
private System.Windows.Forms.MenuItem mniClose;
private System.Windows.Forms.MenuItem mniResize;

private ChildForm child;

public MdiMain()
{
InitializeComponent();

child = new ChildForm();
child.MdiParent = this;
child.Location = new Point( 20, 10 );
child.Show();
}

private void InitializeComponent()
{
this.mainMenu = new System.Windows.Forms.MainMenu();
this.mniTopFile = new System.Windows.Forms.MenuItem();
this.mniExit = new System.Windows.Forms.MenuItem();
this.mniTopActions = new System.Windows.Forms.MenuItem();
this.mniOpen = new System.Windows.Forms.MenuItem();
this.mniClose = new System.Windows.Forms.MenuItem();
this.mniResize = new System.Windows.Forms.MenuItem();
//
// mainMenu
//
this.mainMenu.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {

this.mniTopFile,

this.mniTopActions});
//
// mniTopFile
//
this.mniTopFile.Index = 0;
this.mniTopFile.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {

this.mniExit});
this.mniTopFile.Text = "File";
//
// mniExit
//
this.mniExit.Index = 0;
this.mniExit.Text = "Exit";
this.mniExit.Click += new System.EventHandler(this.mniExit_Click);
//
// mniTopActions
//
this.mniTopActions.Index = 1;
this.mniTopActions.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {

this.mniOpen,

this.mniClose,

this.mniResize});
this.mniTopActions.Text = "Actions";
//
// mniOpen
//
this.mniOpen.Index = 0;
this.mniOpen.Text = "Open";
this.mniOpen.Click += new System.EventHandler(this.mniOpen_Click);
//
// mniClose
//
this.mniClose.Index = 1;
this.mniClose.Text = "Close";
this.mniClose.Click += new System.EventHandler(this.mniClose_Click);
//
// mniResize
//
this.mniResize.Index = 2;
this.mniResize.Text = "Resize";
this.mniResize.Click += new
System.EventHandler(this.mniResize_Click);
//
// MdiMain
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(592, 473);
this.IsMdiContainer = true;
this.Menu = this.mainMenu;
this.Name = "MdiMain";
this.Text = "MdiMain";
}

[STAThread]
static void Main()
{
Application.Run(new MdiMain());
}

private void mniOpen_Click(object sender, System.EventArgs e)
{
this.child.Location = new Point( 20, 10 );
this.child.Size = new Size( 350, 400 );
this.child.Show();
}

private void mniClose_Click(object sender, System.EventArgs e)
{
this.child.Hide();
}

private void mniResize_Click(object sender, System.EventArgs e)
{
this.child.Size = new Size( 350, 400 );
}

private void mniExit_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
} // class MdiMain

public class ChildForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel pnlMain;
private System.Windows.Forms.Label labelTopLeft;
private System.Windows.Forms.Label labelBottomLeft;
private System.Windows.Forms.Label labelTopRight;
private System.Windows.Forms.Label labelBottomRight;
private System.Windows.Forms.TextBox textBoxTopLeft;
private System.Windows.Forms.TextBox textBoxBottomLeft;
private System.Windows.Forms.TextBox textBoxTopRight;
private System.Windows.Forms.TextBox textBoxBottomRight;

public ChildForm()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.pnlMain = new System.Windows.Forms.Panel();
this.textBoxBottomRight = new System.Windows.Forms.TextBox();
this.textBoxTopRight = new System.Windows.Forms.TextBox();
this.textBoxBottomLeft = new System.Windows.Forms.TextBox();
this.textBoxTopLeft = new System.Windows.Forms.TextBox();
this.labelBottomRight = new System.Windows.Forms.Label();
this.labelTopRight = new System.Windows.Forms.Label();
this.labelBottomLeft = new System.Windows.Forms.Label();
this.labelTopLeft = new System.Windows.Forms.Label();
this.pnlMain.SuspendLayout();
this.SuspendLayout();
//
// pnlMain
//
this.pnlMain.AutoScroll = true;
this.pnlMain.Controls.Add(this.textBoxBottomRight);
this.pnlMain.Controls.Add(this.textBoxTopRight);
this.pnlMain.Controls.Add(this.textBoxBottomLeft);
this.pnlMain.Controls.Add(this.textBoxTopLeft);
this.pnlMain.Controls.Add(this.labelBottomRight);
this.pnlMain.Controls.Add(this.labelTopRight);
this.pnlMain.Controls.Add(this.labelBottomLeft);
this.pnlMain.Controls.Add(this.labelTopLeft);
this.pnlMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlMain.Location = new System.Drawing.Point(0, 0);
this.pnlMain.Name = "pnlMain";
this.pnlMain.Size = new System.Drawing.Size(342, 373);
this.pnlMain.TabIndex = 0;
//
// textBoxBottomRight
//
this.textBoxBottomRight.Location = new System.Drawing.Point(270,
180);
this.textBoxBottomRight.Name = "textBoxBottomRight";
this.textBoxBottomRight.Size = new System.Drawing.Size(60, 20);
this.textBoxBottomRight.TabIndex = 7;
this.textBoxBottomRight.Text = "Text Four";
//
// textBoxTopRight
//
this.textBoxTopRight.Location = new System.Drawing.Point(270, 20);
this.textBoxTopRight.Name = "textBoxTopRight";
this.textBoxTopRight.Size = new System.Drawing.Size(60, 20);
this.textBoxTopRight.TabIndex = 6;
this.textBoxTopRight.Text = "Text Three";
//
// textBoxBottomLeft
//
this.textBoxBottomLeft.Location = new System.Drawing.Point(100, 180);
this.textBoxBottomLeft.Name = "textBoxBottomLeft";
this.textBoxBottomLeft.Size = new System.Drawing.Size(60, 20);
this.textBoxBottomLeft.TabIndex = 3;
this.textBoxBottomLeft.Text = "Text Two";
//
// textBoxTopLeft
//
this.textBoxTopLeft.Location = new System.Drawing.Point(100, 20);
this.textBoxTopLeft.Name = "textBoxTopLeft";
this.textBoxTopLeft.Size = new System.Drawing.Size(60, 20);
this.textBoxTopLeft.TabIndex = 2;
this.textBoxTopLeft.Text = "Text One";
//
// labelBottomRight
//
this.labelBottomRight.BorderStyle =
System.Windows.Forms.BorderStyle.FixedSingle;
this.labelBottomRight.Location = new System.Drawing.Point(180, 180);
this.labelBottomRight.Name = "labelBottomRight";
this.labelBottomRight.Size = new System.Drawing.Size(80, 24);
this.labelBottomRight.TabIndex = 5;
this.labelBottomRight.Text = "Label Four";
this.labelBottomRight.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// labelTopRight
//
this.labelTopRight.BorderStyle =
System.Windows.Forms.BorderStyle.FixedSingle;
this.labelTopRight.Location = new System.Drawing.Point(180, 20);
this.labelTopRight.Name = "labelTopRight";
this.labelTopRight.Size = new System.Drawing.Size(80, 24);
this.labelTopRight.TabIndex = 4;
this.labelTopRight.Text = "Label Three";
this.labelTopRight.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// labelBottomLeft
//
this.labelBottomLeft.BorderStyle =
System.Windows.Forms.BorderStyle.FixedSingle;
this.labelBottomLeft.Location = new System.Drawing.Point(10, 180);
this.labelBottomLeft.Name = "labelBottomLeft";
this.labelBottomLeft.Size = new System.Drawing.Size(80, 24);
this.labelBottomLeft.TabIndex = 1;
this.labelBottomLeft.Text = "Label Two";
this.labelBottomLeft.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// labelTopLeft
//
this.labelTopLeft.BorderStyle =
System.Windows.Forms.BorderStyle.FixedSingle;
this.labelTopLeft.Location = new System.Drawing.Point(10, 20);
this.labelTopLeft.Name = "labelTopLeft";
this.labelTopLeft.Size = new System.Drawing.Size(80, 24);
this.labelTopLeft.TabIndex = 0;
this.labelTopLeft.Text = "Label One";
this.labelTopLeft.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// ChildForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.AutoScroll = true;
this.ClientSize = new System.Drawing.Size(342, 373);
this.Controls.Add(this.pnlMain);
this.Name = "ChildForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "ChildForm";
this.pnlMain.ResumeLayout(false);
this.ResumeLayout(false);
}
} // class ChildForm
}
 
L

Linda Liu [MSFT]

Hi Dave,

Thank you for posting.

This is a quick not to let you know that I am performing research on this
issue and will get back to you as soon as possible. I appreciate your
patience.

Sincerely,
Linda Liu
Microsoft Online Community Support

====================================================
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
====================================================
 
L

Linda Liu [MSFT]

Hi Dave,

Thank you for your post. From your post, my understanding on this issue is:
you find that the controls on a panel in a Windows Form will be not visible
after some operations are done on the form. You wish to know whether there
is a work-around. If I'm off base, please feel free to let me know.

For research, I have created a new project in Visual Studio .Net 2003
according to the method described in your email.
The following is the procedure of my test:
1. At the beginning, all labels and textboxes on the panel in the child
form are visible and there is no scroll bars on the panel.
2. Resize the child form to be smaller with the mouse, and the panel is
resized to be smaller as well because the panel's Dock property has been
set to Fill. At this time, some of the controls on the panel are placed
outside of the bound of the panel. For the panel's AutoScroll property has
been set True, corresponding scroll bar appears.
3. Drag the scroll bar and move the panel's visible area to the
bottom-right corner which makes the controls in the top-left corner not
visible. Then if I resize the child form to the previous size
programmatically, all controls on the panel are visible again and the
locations of them are the same as the beginning. But if I hide the child
form first and then resize it programmatically, after the child form is
shown again, the size of the child form is as the same as the beginning,
scroll bars on the panel disappears and the locations of the controls are
the same as the locations after I drag the scroll bar just now. The
controls previous in the panel's left-top corner are not reachable now.

There is a starting point for a panel. When there's no scroll bar on the
panel or the panel's visible area is moved to the top-left corner, the
starting point is located on the top-left point of the panel and the
panel's AutoScrollPosition is {0, 0}. The location property of a control
on the panel is relative to the top-left corner. If there's a scroll bar on
the panel and scroll the panel, the location of the control will change and
the panel's AutoScroll Position property will change, but relative position
between the control and starting point will not change. If the relative
position between the control and starting point changes, the location of
the control when the Panel's AutoScrollPosition is {0, 0} will change. If
the location becomes negative, the control will not be reachable.

So it seems that the starting point of the panel in the child form has been
changed when resizing the form programmatically while it is hidden.
Try not displaying the child form in the MDI Parent. Removing the sentence
"child.MdiParent = this;" can make the child form not display in the MDI
Parent. I found this phenomenon doesn't exist. Thus I may make a
conclusion that starting point of the panel in the child form will be
changed when resizing it programmatically while it is hidden and opened in
a MDI Parent.

If you are going to resize a child form opened in a MDI Parent
programmatically, you should do it when the child form is shown.

Hope this is helpful to you.
If you have any other concerns or need anything else, please let me know.



Sincerely,
Linda Liu
Microsoft Online Community Support

====================================================
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
====================================================
 
G

Guest

Linda,

Based on your explanation of what you found during your research, I conclude
that there is an unexpected and undocumented behavior that occurs when the
MDI style is used. This is unfortunate since I must redesign my application
to account for this behavior.

As an alternative, is there a way that I could catch the Hide event and
force any contained scroll bars to their starting point and then hide the
form?

Thanks,
Dave
 
L

Linda Liu [MSFT]

Hi Dave,
Thank you for your reply.
I think you can set the panel's AutoScrollPosition to the point {0,0} in
the child form's VisibleChanged event handling method to force any
contained scroll bars to their starting point.
The following is a sample.

private void ChildForm_VisibleChanged(object sender, System.EventArgs e)
{
if (this.Visible==false)
{
this.panel1.AutoScrollPosition = new Point(0,0);
}
}

Thus the starting point of the panel in the child form will not be changed
by its MDI Parent after the child form is resized smaller, scrolled to the
Right-Bottom corner, hidden and resized programmatically.

If you have any other concerns or need anything else, please don't hesitate
to let me know.



Sincerely,
Linda Liu
Microsoft Online Community Support

====================================================
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
====================================================
 
G

Guest

Linda,

I have put in place a temporary solution to this issue. I now catch the
request to hide the form and retsore its size before actually calling the
form's Hide method. This will mitigate the issue for now.

I still believe this is a defect in the Microsoft Windows.Forms code. I
can't see how anyone would consider this correct behavior (allowing controls
to become unreachable without programmatically do so).

We plan to move to VS 2005 later this year. Does this behavior occur in the
VS 2005 code?

Thanks,
Dave
 
L

Linda Liu [MSFT]

Hi Dave,

Thank you for your reply.

Yes, I think this is a problem in VS2003 too. I had a test in VS2005 in
order to find out whether this problem exists in it. Unfortunately, the
result of my test is that the problem still exist.

Thank you for finding out the problem. This information will be added to
Microsoft's database. We really value having you as a Microsoft customer.

If you have any other questions or concerns, please don't hesitate to
contact us. It is always our pleasure to be of assistant.

Have a nice day!

Sincerely,
Linda Liu
Microsoft Online Community Support

====================================================
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
====================================================
 
G

Guest

Linda,

Thanks for checking the VS 2005 version. I will keep my current solution in
place when we roll to it. You can consider this posting closed.

I hope you have a nice day as well.

Thanks ,
Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top