Introduction
The first time I saw in new office 2007 system, I got attracted by the new user interface changes; the things that attracted me the most, were, of course, the new Ribbon and the SuperTooltip. I wanted to get these two controls in my own window applications. Since then, I've finished the SuperToolTip and started working on the Ribbon.
After doing a little research, I found out that I am not the only one that thought of a SuperToolTip control. In this article you will learn how to create such a control. I will use 100% C# with no native Windows API. The control will also have a very rich design time support.
Figure 1: The SuperTooltip with a brief description and an example
Figure 2: The superTooltip can also include images
My first hurdle was to create a popup window without using the windows APIs - luckily I found this blog post, which explained an easy way to create a popup window. All you require is a ToolStip DropDown and a ToolStripControlHost instance and the Control you want to appear in the popup window as shown in figure 1.
Code Listing 1
My second hurdle was to implement the SuperTooltip without the need to invoke any windows APIs, I googled around and the first search result was a post in Jensen Harris' Blog one of the MS Office guys. This blog post was the starting point for me in the journey of collecting the needed features for the SuperTooltip.
What does this article cover?
This section will describe the different aspects the SuperToolTip library went through.
Feature List
I summed up all the features I needed and exposed them through these properties.
Properties for each attached control
- Nice looking Gradient Back color through three properties:
BackgroundGradientBegin: The starting color of the background gradient.
BackgroundGradientMiddle: The middle color of the background gradient.
BackgroundGradientEnd: The end color of the background gradient.
- Customizing the Header through these properties:
HeaderText: Text to be displayed in the header.
HeaderFont: Font of the text in the header.
HeaderForeColor: Color of the text in the header.
ShowHeader: Indication to show or hide the header.
ShowHeaderSeparator: Indication to show or hide the header separator.
- Customizing the Footer through these properties:
FooterText: Text to be displayed in the footer.
FooterForeFont: Font of the text in the footer.
FooterColor: Color of the text in the footer.
FooterImage: The image to show in the left part of the footer
ShowFooter: Inidication to show or hide the footer.
ShowFooterSeparator: Indication to show or hide the footer separator.
- Customizing the Body:
BodyText: The body text.
BodyFont: Font of the text in the body.
BodyForeColor: Color of the text in the body.
BodyImage: The image to show in the left part of the body.
The SuperToolTip component
The SuperToolTip component is the coordinator of all these classes to work together correctly.
SuperToolTipWindow: Derived from ToolStripDropDown which is the window itself that is shown.
SuperToolTipControlHost: Derived from ToolStripControlHost which hosts the usercontrol in the window.
SuperToolTipWindowData: Derived from UserControl that has the controls which appear in the tooltip window described more later.
SuperToolTipInfo: Derived from Object which contains all the properties to be exposed for controls.
SuperToolTipInfoWrapper: Derived from Object which wraps a SuperToolTipInfo with a boolean variable to determine if it is used or not.
As described above we only need one instance of each of the SuperToolTipWindow, SuperToolTipControlHost and SuperToolTipWindowData. While for each control on the form we need one SuperToolTipInfoWrapper which in turn wraps one SuperToolTipInfo that contains the actual data to be displayed. Therefore, I have used a Dictionary<Control, SuperToolTipInfoWrapper> list.
The SuperToolTip Window
The SuperToolTipWindow can do nothing on its own. It is a window wrapper of the WindowData UserControl which is shown in listing 2.
Code Listing 2
The SuperToolTipWindowData control.
The SuperToolTipWindowData is derived from the UserControl. It contains all the data needed for a SuperToolTip window which is described in the following figure.
Figure 3: The SuperToolTipWindowData
NOTE: To have a flexible window all controls AutoSize are set to true with an AutoSizeMode set to GrowOnly.
The SuperToolTipInfo class
This class acts only as the container or the temporary storage of each control's tooltip data. It contains the following properties.
Table 1: Provided Properties for each control
| Category |
Associated Properties |
| BackgroundColor |
BackgroundGradientBegin BackgroundGradientMiddle BackgroundGradientEnd |
| Header Properties |
ShowHeader ShowHeaderSeparator HeaderText HeaderFont HeaderForeColor |
| Body Properties |
BodyText BodyFont BodyForeColor BodyImage |
| Footer Properties |
ShowFooter ShowFooterSeparator FooterText FooterFont FooterForeColor FooterImage |
Very rich design time support
In the SuperTooltip component I tried to use most of the design time environment services, the services I used here are:
TypeConverter
UITypeEditor
ExtenderProvider
In this section I will describe in details what and how to make them in our own custom controls useful.
Arranging the provided properties using TypeConverters.
Type Converters are classes that define how classes are converted to and from other data types. In Design-Time they are used to convert to and from strings because all property values in the property grid are shown as strings.
Common .NET Type Converters
The .NET framework is already equipped with several useful and reusable type converters. One of them is the ExpandableObjectConverter which is located in the System.ComponentModel namespace. This converter converts objects to expandable representations. It overrides GetProperties and GetPropertiesSupported to return the properties through the GetProperties method of the TypeDescriptor. The Result of attaching this type converter to a complex object is shown in the below figure.
Figure 4: ExpandableObject example
You can achieve a similar behaviour by attaching the TypeConverter to your complex property using the TypeConverterAttribute.
Code Listing 3
Providing editing assistance using the UITypeEditor
To help developers manage the SuperToolTip for each component I built a SuperToolTipEditor which is derived from UITypeConverter the editor is as shown below.
Figure 5: The SuperToolTip Editor

The implementation of this editor was quit easy. The following section desribes the required steps to create the editor:
- Create a windows form with buttons having a
DialogResult to be used as the Editing Dialog.
- Derive a class from
UITypeEditor and override two methods shown in the code listing 4.
Code Listing 4
- Attach the TypeEditor with the Property being edited.
Code Listing 5
Extending other controls using ExtenderProvider
By adding the IExtenderProvider interface to our component we have a control extender. The idea of this interface is to provide some services to other controls, to give them richer design time support. This Extender component extends other classes (controls) to give them more properties they don't own.
This interface provides a single method CanExtend, as shown in code listing 6 which expects an object passed to it, and it returns a boolean as an answer. The object passed to this method represents the selected control at design time, and the bool result specifies if the class that implements this method should provide its services to this object or not.
Code Listing 6
Based on the result of this call, the VS designer The Design Time Environment decides whether to provide the specified service to the control or not, so when you select a control, the designer calls this method at design time, passing the selected control to it as a parameter, and if its get true, the provided functionality will appear in the selected control property page (and in the code too) as a new property, exactly as if it was implemented in the original control code.
That's not it. Yes we already have an extender that will extend other controls but we didn't tell which properties this extender will give to other controls. For each property we want to provide we follow the following steps:
- Decorate the component with the
ProvidePropertyAttribute and give the PropertyName in attribute constructor.
- Provide two methods with the names
GetPropertyName and SetPropertyName for the get and set of that property, any design time attributes can be added to the GetPropertyName method, just take care of the property casing.
An Example is shown in code listing 7.
Code Listing 7
As shown in the code listing the Get returns the value that the editor needs, the Set takes the just edited value. Both Get and Set take a control as a parameter that is being edited.
As you can see in the image below the
PropertyGrid of a
Button control contains the
SuperStuff property due to the existence of the
SuperToolTip component in the windows form.
Figure 6: Button Properties
What's next?
Next versions of this component should include much more interactivity and enhanced user interface like:
- Balloon tips
- Embedded controls
- More schemes
Revision History
| Version |
Date |
Comments |
| 1.0 |
20.5.2007 |
Initial release |
Summary
In this article you have learned how to implement the SuperTooltip component. Please leave a comment or any questions (if needed) and report any bugs you encounter.
Downloads
References
Top Articles in this category
Settings Manager for Windows Vista Sidebar Gadgets
SettingsManager is a JavaScript library that allows Windows Vista Sidebar gadgets to persist common settings that all gadget instances have access to.
Barcode image generation made easy
In this article we are going to generate barcodes in .NET. Barcode-aware devices, such as scanners and printers, are readily available on the market, as long as the barcodes we generate follow the standards.We will implement barcode generation using Microsoft Ajax in a web application.
ORM in .NET 3.5
This article covers a general introduction to ORM concepts, the approach that .NET 3.5 takes, and how it compares to these other packages.
Foundations of Programming - Part 3 Persistence
The Foundations of Programming series looks at a number of key concepts, techniques and tools specifically designed to help developers meet the growing complexity of enterprise systems. Based on proven principals like unit testing, domain driven design, dependency injection and O/R Mappers, the series is aimed at developers interested in helping themselves.
Introduction to 3-Tier Architecture
Brian Mains explains the benefits of a 3-tier architecture.
|
|
Please login to rate or to leave a comment.