Why this does not work?

J

Juan C. Olivares

Hi:

This is a little program. It has a thread that calls trough Invoke to a
method called Draw. The Draw method draw elements within the Panel control.

For some reason, the program does not close sometimes. Please semd me
comments about this.

Thanks!
Juan C. Olivares

// project created on 11-07-2003 at 0:31
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace MyFormProject
{
delegate void DelegateCallDraw ();
class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panel;
private DelegateCallDraw CallDraw;
public MainForm()
{
InitializeComponent();
panel.AutoScroll = true;
// Add controls
this.Draw ();
// Create delegate
CallDraw = new DelegateCallDraw (Draw);
// StartThread
Thread thread = new Thread (new ThreadStart (StartTimer));
thread.Start ();
}
// This method is used in the forms designer.
// Change this method on you own risk
void InitializeComponent() {
this.panel = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel
//
this.panel.Location = new System.Drawing.Point(16, 16);
this.panel.Name = "panel";
this.panel.Size = new System.Drawing.Size(264, 128);
this.panel.TabIndex = 0;
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 161);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.panel});
this.Name = "MainForm";
this.Text = "This is my form";
this.ResumeLayout(false);
}
private void Draw ()
{
panel.Controls.Clear ();
panel.SuspendLayout ();
for (int i = 1; i <= 20; i++) {
TextBox tb = new TextBox ();
tb.Text = i.ToString ();
tb.Location = new Point (0, (i - 1) * tb.Height);
panel.Controls.Add (tb);
}
panel.ResumeLayout ();
}
private void StartTimer ()
{
while (true) {
// Sleep 10 secs
Thread.Sleep (1000 * 10);
// Call draw
this.Invoke (this.CallDraw);
}
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MainForm());
}
}
}
 
1

100

Hi Juan,
The problem probably is one well known bug in the frame work, which (as far
as I know) MS doesn't recognize as a bug so far.

The bad line is:
panel.Controls.Clear ();
and control validation

If you remove control which is currently focused the form fails to clear
some internal stuff and tries to validate this control. As a result of this,
Form.Closing event receives event args with Cancel property set to 'true',
which stops the form and the application from closing.
There are couple of work arounds:
1. To swhitch the focus on something that is not going to be removed prior
to removing - I personally dislike this.
2. To call Form.OnControlRemoved (and pass a reference to the control) prior
or after removing the control. If you call control.Dispose you have to call
OnControlRemove before disposing the control.

in your case something like
foreach(Control ctrl in panle.Controls)
{
this.OnControlRemove(new ControlEventArgs(ctrl));
}
panel.Controls.Clear()

HTH
B\rgds
100

Juan C. Olivares said:
Hi:

This is a little program. It has a thread that calls trough Invoke to a
method called Draw. The Draw method draw elements within the Panel control.

For some reason, the program does not close sometimes. Please semd me
comments about this.

Thanks!
Juan C. Olivares

// project created on 11-07-2003 at 0:31
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace MyFormProject
{
delegate void DelegateCallDraw ();
class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panel;
private DelegateCallDraw CallDraw;
public MainForm()
{
InitializeComponent();
panel.AutoScroll = true;
// Add controls
this.Draw ();
// Create delegate
CallDraw = new DelegateCallDraw (Draw);
// StartThread
Thread thread = new Thread (new ThreadStart (StartTimer));
thread.Start ();
}
// This method is used in the forms designer.
// Change this method on you own risk
void InitializeComponent() {
this.panel = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel
//
this.panel.Location = new System.Drawing.Point(16, 16);
this.panel.Name = "panel";
this.panel.Size = new System.Drawing.Size(264, 128);
this.panel.TabIndex = 0;
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 161);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.panel});
this.Name = "MainForm";
this.Text = "This is my form";
this.ResumeLayout(false);
}
private void Draw ()
{
panel.Controls.Clear ();
panel.SuspendLayout ();
for (int i = 1; i <= 20; i++) {
TextBox tb = new TextBox ();
tb.Text = i.ToString ();
tb.Location = new Point (0, (i - 1) * tb.Height);
panel.Controls.Add (tb);
}
panel.ResumeLayout ();
}
private void StartTimer ()
{
while (true) {
// Sleep 10 secs
Thread.Sleep (1000 * 10);
// Call draw
this.Invoke (this.CallDraw);
}
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MainForm());
}
}
}
 
J

Juan C. Olivares

Thanks ;)

100 said:
Hi Juan,
The problem probably is one well known bug in the frame work, which (as far
as I know) MS doesn't recognize as a bug so far.

The bad line is:
panel.Controls.Clear ();
and control validation

If you remove control which is currently focused the form fails to clear
some internal stuff and tries to validate this control. As a result of this,
Form.Closing event receives event args with Cancel property set to 'true',
which stops the form and the application from closing.
There are couple of work arounds:
1. To swhitch the focus on something that is not going to be removed prior
to removing - I personally dislike this.
2. To call Form.OnControlRemoved (and pass a reference to the control) prior
or after removing the control. If you call control.Dispose you have to call
OnControlRemove before disposing the control.

in your case something like
foreach(Control ctrl in panle.Controls)
{
this.OnControlRemove(new ControlEventArgs(ctrl));
}
panel.Controls.Clear()

HTH
B\rgds
100

Juan C. Olivares said:
Hi:

This is a little program. It has a thread that calls trough Invoke to a
method called Draw. The Draw method draw elements within the Panel control.

For some reason, the program does not close sometimes. Please semd me
comments about this.

Thanks!
Juan C. Olivares

// project created on 11-07-2003 at 0:31
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace MyFormProject
{
delegate void DelegateCallDraw ();
class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panel;
private DelegateCallDraw CallDraw;
public MainForm()
{
InitializeComponent();
panel.AutoScroll = true;
// Add controls
this.Draw ();
// Create delegate
CallDraw = new DelegateCallDraw (Draw);
// StartThread
Thread thread = new Thread (new ThreadStart (StartTimer));
thread.Start ();
}
// This method is used in the forms designer.
// Change this method on you own risk
void InitializeComponent() {
this.panel = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel
//
this.panel.Location = new System.Drawing.Point(16, 16);
this.panel.Name = "panel";
this.panel.Size = new System.Drawing.Size(264, 128);
this.panel.TabIndex = 0;
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 161);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.panel});
this.Name = "MainForm";
this.Text = "This is my form";
this.ResumeLayout(false);
}
private void Draw ()
{
panel.Controls.Clear ();
panel.SuspendLayout ();
for (int i = 1; i <= 20; i++) {
TextBox tb = new TextBox ();
tb.Text = i.ToString ();
tb.Location = new Point (0, (i - 1) * tb.Height);
panel.Controls.Add (tb);
}
panel.ResumeLayout ();
}
private void StartTimer ()
{
while (true) {
// Sleep 10 secs
Thread.Sleep (1000 * 10);
// Call draw
this.Invoke (this.CallDraw);
}
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MainForm());
}
}
}
 

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