Link to home
Start Free TrialLog in
Avatar of ichikuma
ichikumaFlag for United States of America

asked on

Subclass a TextBox control for dynamic tooltips

I have an application that has hundreds of controls and tooltips for each control.  What I'm trying to do is create a "smart" TextBox control that during design time, I can specify the tooltip, which actually points to a value in a hashtable so when the control loads, it can go get it's tooltip.  I'm running into a couple of issues while trying to do this:

1.  I created an Interface that all my forms/controls will derive from so I can be sure the Parent where my smart TextBox lives implements the functions I need.  This creates an issue though, if I drop my smart text box on a form, have the form derive from my interface and then try to open the form up in design mode, it fails because I'm casting the "Parent" to my interface.  It fails here:

protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);

            IFormBase ctrl = this.Parent as IFormBase; //This causes the error.
            ToolTip tt = ctrl.GetToolTipCtrl();
            tt.SetToolTip(this, ctrl.GetToolTip(tt.GetToolTip(this)));
        }

2.  I have a checkbox on my form that switches between units of measure.  In the OnChanged event, I need to refresh my smart text box so it will bring back the tooltip with the correct units specified.  Is there some kind of Invalidate method I can call on the form that will cause all the controls to update themselves?

I've uploaded my sample project file, any guidance would be greatly appreciated.
ToolTips.zip
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

I would test for DesignMode:


protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);

            if (!this.DesignMode)
            {
                IFormBase ctrl = this.Parent as IFormBase; 
                ToolTip tt = ctrl.GetToolTipCtrl();
                tt.SetToolTip(this, ctrl.GetToolTip(tt.GetToolTip(this)));
             }
        }

Open in new window

Avatar of ichikuma

ASKER

Didn't even know there was such a thing.  That solved my first and biggest issue, thanks.  Do you have any ideas about how to tell each control to go retrieve the new tooltip when the checkbox is changed?  I know in the old days of MFC, you could "Invalidate" the UI and each control would redraw itself but I don't know of a way to do that in C#.

Thanks again.
What do you mean by "checkbox is changed"?  Are you talking about the Checked property?

If you are sub-classing a CheckBox, then there is an override available for the OnCheckedChanged:


protected override void OnCheckedChanged(EventArgs e)
        {
            base.OnCheckedChanged(e);

            if (!this.DesignMode)
            {
                IFormBase ctrl = this.Parent as IFormBase;
                ToolTip tt = ctrl.GetToolTipCtrl();
                tt.SetToolTip(this, ctrl.GetToolTip(tt.GetToolTip(this)));
            } 
        }

Open in new window

Sorry, I guess I did make it more confusing.  In the sample project, if I add a CheckBox to Form1, the same form that contains my SmartTextBox control.  I would then override the checkBox1_CheckedChanged event so I know that it's state has changed.  Let's say I have 20 SmartTextBox controls on Form1, how would I notify each one to update it's tooltip?  This is the problem I'm having, when the user checks/unchecks the checkbox, I need to update my SmartTextBox controls so they know to get the new tooltip.  I guess my SmartTextBox isn't so smart after all :(.

Thanks and sorry for the confusion.
Hmmm...are you asking how to make your "smart" TextBox control smarter, by listening for a CheckBox.CheckChanged event on another control?  Is this a standard CheckBox or a "smart" CheckBox?
That's correct, when the checkbox changes, I want all, in this example, 20 SmartTextBoxes to update their tooltips.

The checkbox will be just a standard checkbox unless you think I should try and make it "smart" somehow to update the SmartTextBoxes.
The question I have is, "How do you want to bind the SmartTextBox to the CheckBox?"
I have the same question, lol.  I was thinking I could possibly use the Observer pattern but not sure how I would make that work with C# already throwing messages.  I would need to somehow let the checkbox send a broadcast message out to all "known" smartTextBoxes so they can update their tooltips.

Am I traveling down the right path or will I end up crashing and burning?
I think I have it...please let me know if I've lost my mind or not ;).

I created a SmartCheckBox, this checkbox has a list<SmartTextBox>.  At design time, the SmartTextBox has to be bound to a SmartCheckBox.  The SmartCheckBox has a method called Subscribe(SmartTextBox) which adds the passed in SmartTextBox to the list of text boxes.  Now, on the SmartCheckBox->CheckedChanged event, I iterate over all of the SmartTextBoxes in the list and call an Update method on each text box, thus implementing the Observer pattern :).  

I hope this is right!

Thanks again for your help.
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Man, now you got me thinking, I've spent the last couple of hours implementing your suggestion.  I must say, it's a much better design than what I was looking at doing.  Thanks again for you help, you've certainly taught me how to fish :).

Take care.
Awesome job of explaining not only a way to get it implmented but also a much more generic way.  I learned a lot from this seemingly easy implementation.