• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 775
  • Last Modified:

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
0
ichikuma
Asked:
ichikuma
  • 7
  • 5
1 Solution
 
Bob LearnedCommented:
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

0
 
ichikumaAuthor Commented:
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.
0
 
Bob LearnedCommented:
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

0
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 
ichikumaAuthor Commented:
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.
0
 
Bob LearnedCommented:
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?
0
 
ichikumaAuthor Commented:
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.
0
 
Bob LearnedCommented:
The question I have is, "How do you want to bind the SmartTextBox to the CheckBox?"
0
 
ichikumaAuthor Commented:
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?
0
 
ichikumaAuthor Commented:
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.
0
 
Bob LearnedCommented:
Hmmm...that sounds like a plan, but lets think outside of the box on this one.  That pattern would lock you into a strong-typed list of SmartTextBox controls for a SmartCheckBox.  What if you need a SmartComboBox, or a SmartListBox, with a list of SmartLabel controls.

It might be more useful to have a "parent" control, and "child" controls.  The child controls could implement an interface that defines a generic event (i.e. StateChanged).  

Scenario:

The SmartCheckBox would be the parent control, and the list of SmartTextBox controls would be the children.  When the parent state is changed, notify all the children to update the tool tip.  You could have the SmartCheckBox implement the ISmartParentControl interface, that would define a Children property as List<ISmartChildControl>.  The ISmartChildControl could have a ParentControl property (ISmartParentControl), that automatically adds the control to the Children collection when the property is set.  Then, you could define the child controls as any type that implement the ISmartChildControl interface.
0
 
ichikumaAuthor Commented:
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.
0
 
ichikumaAuthor Commented:
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.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 7
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now