RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Code Less and Do More with Extender Controls : Page 2

Using .NET extender controls can help you avoid tedious subclassing of existing controls. But what are extender controls and how do you use them? Find out how these "non-visual" controls can be a great design-time short cut for people who want to spend less time writing code.

Okay, What's the Catch?
Implementing CanExtend only allows the development environment to assess whether a class can be utilized to extend a given control. It does not provide the development environment with any information about how the extended property is to function. In order to provide that functionality, custom methods must be added to the extender control. These methods are specifically named and are called by the development environment wherever it needs to change or retrieve the properties that are being added to the controls on the form. From this you can correctly conclude that you can use a single extender control to add multiple custom properties to the controls of a form. Two custom methods are required to implement a single extended property: one to set values and one to retrieve them. Again, these methods must be specifically named:

Get + [property name] 
Set + [property name]
This naming convention is required so that the development environment can locate the methods used to implement the property within the extender provider. It seems somewhat ironic that you are required to use methods to implement a property. It's because the set method requires two parameters in order to operate (and the get method requires one). In both cases, this is one parameter more than is permitted in a typical property implementation.

The Set method accepts two parameters: the component to be extended and the value to which that property is set. The first parameter keeps track of what extended properties have been set to what values for which components of the form. Therefore, any implementation of any extender control needs to include some form of collection management. This example utilizes a hashtable. The set method inserts the value within the collection for the property with the value supplied by the method call (if the value is already there, the set method simply replaces it). Thus, the component parameter acts as the key in the collection object's key value pair.

public void SetSecurityEnableComponent(System.ComponentModel.Component component, string value) 
  if (value == null) 
    value = string.Empty;

  if (value.Length == 0) 
    roleTexts[component] = value;

public string GetSecurityEnableComponent(System.ComponentModel.Component  c) 
  string text = (string)roleTexts[c];
  if (text == null) 
    text = string.Empty;
  return text;
The get method is far simpler. When this method is called (queried) for a component, it either returns (replies) with the value stored in the collection for the given component or it returns a default value if value has been applied for the extended property for the given control.

To review:

  • Declare the extender provider component to be derived from System.ComponentModel.Component and to implement the IExtenderProvider interface.
  • Provide a CanExtend method to specify what form controls the provider will extend.
  • Provide a Get and Set method for the extended properties you wished to provide.
  • Provide an internal mechanism to keep track of the values of your extended properties for multiple form controls.
Are We There Yet?
There is only one more crucial element required to pull all this together. You need to tell the designer that the property is available and tell it how to set/retrieve the property (ie. is the property a string, a list of predefined values, etc.). You can do this by providing a class level custom attribute, specifically, the ProvideProperty attribute, which provides critical keys to the design time environment.

[ProvideProperty("SecurityEnableComponent",typeof(System.ComponentModel.Component ))]
[ProvideProperty("Two",typeof(System.ComponentModel.Component ))]
public class SecurityEnableComponent : System.ComponentModel.Component,
The ProvideProperty attribute relays the name of the property. In the example above, the property becomes SecurityEnableComponent.

Next, it specifies the controls or components to which each property can be applied. In this case, the property should be applied to all components. Remember, you can use the CanExtend method for more fine-grain control over specific classes of components.

Finally, you can use ProvideProperty to tell the designer how to display and manipulate the value of the property. In this example, and in most cases, the designer can use a default property editor (such as the string property editor). Obviously, more complex properties might require a custom property editor (such as a font property or an RGB color property). In these cases, you would specify a custom property editor as the third attribute of the ProvideProperty constructor.

The Value Add
The extended properties will not be available in the controls themselves at runtime. In order to access the property values, you need to access the extender provider control directly. Now all you need to do is implement it. Simply package the component into an assembly class library (DLL), use the System.Drawing.ToolboxBitmapAttribute to provide a custom Toolbox Icon, and add the project into the IDE's Toolbox. Now, you're hooked up—code less, do more; have fun!

Jonathan Lurie is a consultant, and enterprise software development trainer who holds a number of certifications including MCSE, MCSD, Java Certified Programmer, and IBM Certified XML Developer. He lives in Manhattan Beach, CA and enjoys programming, writing, and playing beach volleyball.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date