Bug in ToolTip component?

  • Thread starter Thread starter Edward
  • Start date Start date
E

Edward

Hi all,
In my application I have modal form and controls on this
form have tooltips. I do not recreate instance of the
form, only hide it and show again. But after second
ShowModal all tooltips disapear. Is this known bug, or I
do something wrong?
Sample code illustrates this behavior:
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button
button1;
private System.Windows.Forms.ToolTip
toolTip1;
public Form1()
{
this.button1 = new
System.Windows.Forms.Button();
this.toolTip1 = new
System.Windows.Forms.ToolTip();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new
System.Drawing.Point(16, 8);
this.button1.Name = "button1";
this.button1.Size = new
System.Drawing.Size(232, 56);
this.button1.TabIndex = 0;
this.button1.Text = "Hide Dialog";
this.toolTip1.SetToolTip
(this.button1, "ToolTop for Button");
this.button1.Click += new
System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new
System.Drawing.Size(5, 13);
this.ClientSize = new
System.Drawing.Size(264, 70);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Modal Dialog";
this.ResumeLayout(false);
}

[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.
f.ShowDialog();
}

private void button1_Click(object sender,
System.EventArgs e)
{
this.Hide();
this.button1.Text = "Were is my
tooltip?";
}
}

Thanks Edward.
 
In my application I have modal form and controls on this
form have tooltips. I do not recreate instance of the
form, only hide it and show again.

That's your problem. ShowDialog() automatically calls Dispose() on the
form before it returns -- it wasn't designed to be called more than once
on the same form instance.

Assuming that you do need to call ShowDialog() and can't just change it
to showing the form non-modally, you have two options:

1. Create a new instance of the form each time you need to show it. Or,

2. Modify the code that the form designer added to your form's
Dispose() method, and leave out the call to components.Dispose().
You'll still want to make sure that components.Dispose() gets called
when you really are done with the form, since things like data access
components do need to get cleaned up; but if you make sure it isn't
called every time that ShowDialog() calls Dispose(), then your tooltips
(and ErrorProviders and whatever else) should keep working even if you
show the form multiple times.
 
Joe White said:
That's your problem. ShowDialog() automatically calls Dispose() on the
form before it returns -- it wasn't designed to be called more than once
on the same form instance.

Hi Joe,

I don´t know about the Tooltip problem, but your statement of above called
my attention because I have seen MS examples where they call explicitly the
Dispose method and if you add the line of below you will see that the form
is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns False

f.ShowDialog();
}


Am I missing something?

Carlos
 
Ack!

You're right -- I goofed. ShowDialog does destroy the window handle
before it returns (*that's* what I was thinking of). But you're right,
it doesn't call Dispose. Thanks for correcting me!

Which puts things back to square one on the tooltip question... sigh.
Maybe I can take another look at it in the morning.

That's your problem. ShowDialog() automatically calls Dispose() on the
form before it returns -- it wasn't designed to be called more than once
on the same form instance.


Hi Joe,

I don´t know about the Tooltip problem, but your statement of above called
my attention because I have seen MS examples where they call explicitly the
Dispose method and if you add the line of below you will see that the form
is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns False

f.ShowDialog();
}


Am I missing something?

Carlos
 
Hi Joe & Carlos,
Thank you for attention.
From MSDN Help:
<b>Note When the Close method is called on a Form
displayed as a modeless window, you cannot call the Show
method to make the form visible, because the form's
resources have already been released. To hide a form and
then make it visible, use the Control.Hide method.</b>
1. I do not use .Close, I use .Hide.
2. Automatic disposing perfomed only for modeless windows
( e.g. when you call .Show method ). I use .ShowDialog
and get modal form. My form is alive and only tooltips
are dead after second .ShowDialog.
There was lot of bugs with modal forms and tooltips in VS
6. I think there is bug. How can i report it to MS?
Does anybody knows workaround fo this problem?
Edward.



-----Original Message-----
Joe White said:
That's your problem. ShowDialog() automatically calls Dispose() on the
form before it returns -- it wasn't designed to be called more than once
on the same form instance.

Hi Joe,

I don´t know about the Tooltip problem, but your statement of above called
my attention because I have seen MS examples where they call explicitly the
Dispose method and if you add the line of below you will see that the form
is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns False

f.ShowDialog();
}


Am I missing something?

Carlos


.
 
Okay, I've taken a little closer look at your code. It looks like what
you're doing is not something that Windows.Forms was designed for.
There may be a bug here, but I don't know -- you're wandering into
territory where "expected behavior" may not even be defined.

Really, hiding a modal dialog doesn't even make sense. What do you
expect to happen when you hide it? Should it still be modal? If so,
then the call to ShowDialog() wouldn't return yet -- it wouldn't return
until you show the form again so you can close it. So your sample code
would just go into an infinite loop when you hide the dialog the first
time, and it would never get around to showing it the second time. On
the other hand, if you think it *should* stop being modal when you hide
it, then doesn't that mean you've closed it? ShowDialog() has to return
a DialogResult, after all, to tell you how the form was closed.

I did a quick test, and Windows.Forms can't seem to make up its mind
whether the modal form gets "closed" or not when you call Hide(). The
form's Closing event gets fired, but the Closed event does not. Strange.

At any rate, hiding a modal form seems to me like a bad idea. Like I
said, it just doesn't make sense. Could you describe what you're
actually trying to do, and we'll see if there's a better way to
accomplish it?

Hi Joe & Carlos,
Thank you for attention.
From MSDN Help:
<b>Note When the Close method is called on a Form
displayed as a modeless window, you cannot call the Show
method to make the form visible, because the form's
resources have already been released. To hide a form and
then make it visible, use the Control.Hide method.</b>
1. I do not use .Close, I use .Hide.
2. Automatic disposing perfomed only for modeless windows
( e.g. when you call .Show method ). I use .ShowDialog
and get modal form. My form is alive and only tooltips
are dead after second .ShowDialog.
There was lot of bugs with modal forms and tooltips in VS
6. I think there is bug. How can i report it to MS?
Does anybody knows workaround fo this problem?
Edward.




-----Original Message-----
Dispose() on the
called more than once
Hi Joe,

I don´t know about the Tooltip problem, but your

statement of above called
my attention because I have seen MS examples where they

call explicitly the
Dispose method and if you add the line of below you will

see that the form
is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns
False

f.ShowDialog();
}


Am I missing something?

Carlos
 
Hi Joe,
My real application is too complicated. It is very
expensive to create instance of the form every time when
it is necessary to show it. Basades this I use .Hide
method only in the sample. In real form I will
use .Close. But it doesn't change fact of the matter,
couse framework do not call .Dispose closing modal dialog
and it could be shown again according with
documentation.
I am agree with you in point of .Close method desrtroy
window handle, and it may be the root of my problem. It
looks like ToolTip component erroneously collect handles
of controls which become invalid on next showing of the
form.
Regards, Edward.
-----Original Message-----
Okay, I've taken a little closer look at your code. It looks like what
you're doing is not something that Windows.Forms was designed for.
There may be a bug here, but I don't know -- you're wandering into
territory where "expected behavior" may not even be defined.

Really, hiding a modal dialog doesn't even make sense. What do you
expect to happen when you hide it? Should it still be modal? If so,
then the call to ShowDialog() wouldn't return yet -- it wouldn't return
until you show the form again so you can close it. So your sample code
would just go into an infinite loop when you hide the dialog the first
time, and it would never get around to showing it the second time. On
the other hand, if you think it *should* stop being modal when you hide
it, then doesn't that mean you've closed it? ShowDialog () has to return
a DialogResult, after all, to tell you how the form was closed.

I did a quick test, and Windows.Forms can't seem to make up its mind
whether the modal form gets "closed" or not when you call Hide(). The
form's Closing event gets fired, but the Closed event does not. Strange.

At any rate, hiding a modal form seems to me like a bad idea. Like I
said, it just doesn't make sense. Could you describe what you're
actually trying to do, and we'll see if there's a better way to
accomplish it?

Hi Joe & Carlos,
Thank you for attention.
From MSDN Help:
<b>Note When the Close method is called on a Form
displayed as a modeless window, you cannot call the Show
method to make the form visible, because the form's
resources have already been released. To hide a form and
then make it visible, use the Control.Hide method.</b>
1. I do not use .Close, I use .Hide.
2. Automatic disposing perfomed only for modeless windows
( e.g. when you call .Show method ). I use .ShowDialog
and get modal form. My form is alive and only tooltips
are dead after second .ShowDialog.
There was lot of bugs with modal forms and tooltips in VS
6. I think there is bug. How can i report it to MS?
Does anybody knows workaround fo this problem?
Edward.




-----Original Message-----
"Joe White" <[email protected]> escribió en el mensaje

That's your problem. ShowDialog() automatically calls
Dispose() on the
form before it returns -- it wasn't designed to be
called more than once
on the same form instance.

Hi Joe,

I don´t know about the Tooltip problem, but your

statement of above called
my attention because I have seen MS examples where
they

call explicitly the
Dispose method and if you add the line of below you
will

see that the form
is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns
False

f.ShowDialog();
}


Am I missing something?

Carlos

.
 
I'm a little curious as to why creating this form is so expensive. If
you've got things like database queries on it, you might be better off
moving these into a separate object, and keep the object around instead
of the form. That may not be your situation at all, but it's just a
thought.

I had another idea about a workaround: putting most of your UI onto a
UserControl, and then dynamically creating a new Form instance, putting
the UserControl onto it, doing a ShowDialog on that Form, and then
setting the UserControl's Parent back to nil in the Form's Closing event
to make sure its state doesn't get messed up when the modal form closes.
But I tried it and it didn't work -- so you may be right about the
ToolTip caching window handles. (And if it does cache window handles,
and never notices when they change, then that's a really poor design...)

I don't suppose there's any way you could make this work with just
showing and hiding the form, instead of using ShowDialog()?

Hi Joe,
My real application is too complicated. It is very
expensive to create instance of the form every time when
it is necessary to show it. Basades this I use .Hide
method only in the sample. In real form I will
use .Close. But it doesn't change fact of the matter,
couse framework do not call .Dispose closing modal dialog
and it could be shown again according with
documentation.
I am agree with you in point of .Close method desrtroy
window handle, and it may be the root of my problem. It
looks like ToolTip component erroneously collect handles
of controls which become invalid on next showing of the
form.
Regards, Edward.

-----Original Message-----
Okay, I've taken a little closer look at your code. It

looks like what
you're doing is not something that Windows.Forms was

designed for.
There may be a bug here, but I don't know -- you're

wandering into
territory where "expected behavior" may not even be
defined.

Really, hiding a modal dialog doesn't even make sense.

What do you
expect to happen when you hide it? Should it still be

modal? If so,
then the call to ShowDialog() wouldn't return yet -- it

wouldn't return
until you show the form again so you can close it. So

your sample code
would just go into an infinite loop when you hide the

dialog the first
time, and it would never get around to showing it the

second time. On
the other hand, if you think it *should* stop being

modal when you hide
it, then doesn't that mean you've closed it? ShowDialog

() has to return
a DialogResult, after all, to tell you how the form was
closed.

I did a quick test, and Windows.Forms can't seem to make

up its mind
whether the modal form gets "closed" or not when you

call Hide(). The
form's Closing event gets fired, but the Closed event

does not. Strange.
At any rate, hiding a modal form seems to me like a bad

idea. Like I
said, it just doesn't make sense. Could you describe

what you're
actually trying to do, and we'll see if there's a better

way to
accomplish it?

Hi Joe & Carlos,
Thank you for attention.
From MSDN Help:
<b>Note When the Close method is called on a Form
displayed as a modeless window, you cannot call the
Show
method to make the form visible, because the form's
resources have already been released. To hide a form
and
then make it visible, use the Control.Hide method.</b>
1. I do not use .Close, I use .Hide.
2. Automatic disposing perfomed only for modeless
windows
( e.g. when you call .Show method ). I use .ShowDialog
and get modal form. My form is alive and only tooltips
are dead after second .ShowDialog.
There was lot of bugs with modal forms and tooltips in
VS
6. I think there is bug. How can i report it to MS?
Does anybody knows workaround fo this problem?
Edward.






-----Original Message-----
"Joe White" <[email protected]> escribió en el mensaje


That's your problem. ShowDialog() automatically
calls
Dispose() on the


form before it returns -- it wasn't designed to be

called more than once


on the same form instance.

Hi Joe,

I don´t know about the Tooltip problem, but your

statement of above called


my attention because I have seen MS examples where
they
call explicitly the


Dispose method and if you add the line of below you
will
see that the form


is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns

False


f.ShowDialog();
}


Am I missing something?

Carlos
 
No way:(
Code can not be separated, becouse of expensive part is
controls creation. Now I have to implement ugly
workarownd - tooltip.RamoveAll & recreation of tooltips
before showing the form.
Thank you for help.
Regards, Edward.
-----Original Message-----
I'm a little curious as to why creating this form is so expensive. If
you've got things like database queries on it, you might be better off
moving these into a separate object, and keep the object around instead
of the form. That may not be your situation at all, but it's just a
thought.

I had another idea about a workaround: putting most of your UI onto a
UserControl, and then dynamically creating a new Form instance, putting
the UserControl onto it, doing a ShowDialog on that Form, and then
setting the UserControl's Parent back to nil in the Form's Closing event
to make sure its state doesn't get messed up when the modal form closes.
But I tried it and it didn't work -- so you may be right about the
ToolTip caching window handles. (And if it does cache window handles,
and never notices when they change, then that's a really poor design...)

I don't suppose there's any way you could make this work with just
showing and hiding the form, instead of using ShowDialog ()?

Hi Joe,
My real application is too complicated. It is very
expensive to create instance of the form every time when
it is necessary to show it. Basades this I use .Hide
method only in the sample. In real form I will
use .Close. But it doesn't change fact of the matter,
couse framework do not call .Dispose closing modal dialog
and it could be shown again according with
documentation.
I am agree with you in point of .Close method desrtroy
window handle, and it may be the root of my problem. It
looks like ToolTip component erroneously collect handles
of controls which become invalid on next showing of the
form.
Regards, Edward.

-----Original Message-----
Okay, I've taken a little closer look at your code.
It

looks like what
you're doing is not something that Windows.Forms was

designed for.
There may be a bug here, but I don't know -- you're

wandering into
territory where "expected behavior" may not even be
defined.

Really, hiding a modal dialog doesn't even make
sense.

What do you
expect to happen when you hide it? Should it still be

modal? If so,
then the call to ShowDialog() wouldn't return yet --
it

wouldn't return
until you show the form again so you can close it. So

your sample code
would just go into an infinite loop when you hide the

dialog the first
time, and it would never get around to showing it the

second time. On
the other hand, if you think it *should* stop being

modal when you hide
it, then doesn't that mean you've closed it?
ShowDialog

() has to return
a DialogResult, after all, to tell you how the form
was

closed.
I did a quick test, and Windows.Forms can't seem to
make

up its mind
whether the modal form gets "closed" or not when you

call Hide(). The
form's Closing event gets fired, but the Closed event

does not. Strange.
At any rate, hiding a modal form seems to me like a
bad

idea. Like I
said, it just doesn't make sense. Could you describe

what you're
actually trying to do, and we'll see if there's a
better

way to
accomplish it?


Edward wrote:

Hi Joe & Carlos,
Thank you for attention.
From MSDN Help:
<b>Note When the Close method is called on a Form
displayed as a modeless window, you cannot call the
Show
method to make the form visible, because the form's
resources have already been released. To hide a form
and
then make it visible, use the Control.Hide method.</b>
1. I do not use .Close, I use .Hide.
2. Automatic disposing perfomed only for modeless
windows
( e.g. when you call .Show method ). I use .ShowDialog
and get modal form. My form is alive and only tooltips
are dead after second .ShowDialog.
There was lot of bugs with modal forms and tooltips in
VS
6. I think there is bug. How can i report it to MS?
Does anybody knows workaround fo this problem?
Edward.






-----Original Message-----
"Joe White" <[email protected]> escribió en el mensaje


That's your problem. ShowDialog() automatically
calls
Dispose() on the


form before it returns -- it wasn't designed to be

called more than once


on the same form instance.

Hi Joe,

I don´t know about the Tooltip problem, but your

statement of above called


my attention because I have seen MS examples where
they
call explicitly the


Dispose method and if you add the line of below you
will
see that the form


is not disposed automatically:


[STAThread]
static void Main()
{
Form f = new Form1();
// First Show
// button1 has tooltip.
f.ShowDialog();
// Second Show ( after Hide )
// tooltip for button1 disappears.

MessageBox.Show(f.IsDisposed.ToString()); // returns

False


f.ShowDialog();
}


Am I missing something?

Carlos

.
 
Back
Top