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
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
What does this article cover?
This section will describe the different aspects the
SuperToolTip library went through.
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
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
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
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.
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
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
||Associated Properties |
Very rich design time support
SuperTooltip component I tried to use most of the design time environment services, the services I used here are:
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
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
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
SetPropertyName for the
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
Set take a control as a parameter that is being edited.
As you can see in the image below the
control contains the
property due to the existence of the
component in the windows form.
Figure 6: Button Properties
Next versions of this component should include much more interactivity and enhanced user interface like:
- Balloon tips
- Embedded controls
- More schemes
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.
Sorry, no bio is available
This author has published 2 articles on DotNetSlackers. View other articles or the complete profile here.
Please login to rate or to leave a comment.