Composite Custom Web Controls in Managed C++

The first two installments of this series got your feet wet in custom Web control development. The first covered some of the prep work required for setting up a Managed C++ custom Web control development environment. The second showed how to create a superclassed custom Web control, the simplest of the three types of custom Web controls.

This installment examines the more advanced—and far more powerful—composite custom Web control. Because the rendered custom Web control is such a meaty topic, I’ll save that for the fourth and final installment.

Composite Custom Web Controls

A composite custom Web control is exactly what its name suggests: a composite of one or more server or HTML controls within a single control. The composite custom control is functionally very similar to the user control. The big difference is that it resides in its own assembly (or one shared with other controls), can be put in the toolbar, and provides WYSIWYG views of the controls it contains when implemented.

On the other hand, composite custom Web controls are more difficult to create than user controls because the Visual Studio.NET designer offers no facility to create them visually. So, the question is: Why use composite controls instead of user controls? You’re better off using a composite custom Web control when distributing the control to multiple Web applications or systems. User controls are better when you are not focusing on re-use (for example, if you are going to use the control only within your site, sticking with the user control makes more sense). Basically, you have to weigh the extra effort it takes to create it versus the amount of re-use you are going to get from it. Also, because a composite custom Web control resides in its own assembly, you will need only one copy of it per machine. User controls are placed within the Web’s assembly and thus are stored in each Web site that uses it.

Creating a composite custom Web control

The steps for creating a composite custom Web control are virtually identical to those for creating a superclassed custom Web control, but that is why you do all that prep work upfront.

  1. Add a new class to a class library. (I’m just using the one created during prep work, but you can create a new class library if you like.) In this case, I called the class SearchControl , but of course you can call it anything you like.
  2. Paste the .h and .cpp code, which you save in the toolbox to the appropriate class files.
  3. Search and replace all instances of the default class name to the name of the new class in both the .h and .cpp files.
  4. In the .cpp file, rename the include file to point to the new .h file you created. I also added a .bmp file of binoculars to use as an icon on the toolbar, and I updated the linker input property.
  5. Compile, remove all old references to the original control library (if you are continuing from an old library like I am), and then add the reference to the new created assembly and a control (or set of controls, in my case) to the toolbar. You should now be able to drag and drop the default control to your designer.

Now, you are ready to create your new composite custom Web control.

The appearance

The first thing you should do is design the look of the control and then create the look and feel without any functionality behind it. When finished, I envision my control will look like Figure 1, which is the control as seen in the designer.

Figure 1. The Control as Seen in the Designer

SearchControl, as you can see, is made up of three server controls (but there are actually four, as you will see in a bit):

  • A Label
  • A TextBox
  • A Button

As I stated previously, the tricky part of composite custom Web controls is that they don’t have a nice drag-and-drop design tool with which to create controls. Instead, you have to do it the old-fashioned way—write the code from scratch. Well, that’s not exactly true. You don’t have to write your server or HTML controls from scratch. (That is what you do with a rendered custom Web control, by the way.) So, how do you go about creating the appearance of the SearchControl?

First, create definitions for the three server controls within the SearchControl class:

Label     *label;
TextBox   *textbox;
Button    *button;

Next, create instances of them in the class constructor:

SearchControl::SearchControl()
{
   label   = new Label();
   textbox = new TextBox();
   button  = new Button();
}

Finally, add them to a composite custom Web control’s child control collection within the class’s CreateChildControls() method:

void SearchControl::CreateChildControls()
{
   Controls->Add(label);
   Controls->Add(textbox);
   Controls->Add(button);
}

The CreateChildControls() method is a virtual method inherited from the Control class, which WebControl inherits.

Note: You don’t need the Render() method because the server and HTML control that make up the composite control can render themselves. Therefore, you can either leave out the method entirely or have the Render() method call the base class:

void SearchControl::Render(HtmlTextWriter *output)
{
   __super::Render(output);
}

Now that you have the basic appearance, you can add some functionality. First, you need some properties to update the labels and the value within the textbox. The previous installment covered properties, so I won’t go into the details again. But, here are the definitions for the properties:

[Bindable(true), Category("Appearance"), DefaultValue("")]
__property void set_Value(String *value);
__property String *get_Value();

[Bindable(true), Category("Appearance"), DefaultValue("")]
__property void set_LabelText(String *value);
__property String *get_LabelText();

[Bindable(true), Category("Appearance"), DefaultValue("")]
__property void set_ButtonText(String *value);
__property String *get_ButtonText();

And here is the code:

String *SearchControl::get_LabelText()
{
   this->EnsureChildControls();
   return label->Text;
}

void SearchControl::set_LabelText(String *value)
{
   this->EnsureChildControls();
   label->Text = value;
}

String *SearchControl::get_Value()
{
   this->EnsureChildControls();
   return textbox->Text;
}

void SearchControl::set_Value(String *value)
{
   this->EnsureChildControls();
   textbox->Text = value;
}

String *SearchControl::get_ButtonText()
{
   this->EnsureChildControls();
   return button->Text;
}

void SearchControl::set_ButtonText(String *value)
{
   this->EnsureChildControls();
   button->Text = value;
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read