Microsoft & .NETVisual C#Creating Custom Web Controls in Managed C++, Part 1

Creating Custom Web Controls in Managed C++, Part 1

A common misunderstanding is that Managed C++ and ASP.NET Web applications are mutually exclusive. Nothing could be further from the truth. Yes, MC++ doesn’t have all the helpful drag-and-drop GUI IDE integration of C# or Visual Basic .NET, but that is not unusual for a C++ developer who always seems to have to do things the hard way.

One area where MC++ and the other .NET languages are on level ground in ASP.NET Web applications is custom Web controls, as there is no fancy IDE integration—just good old hand coding. So, this first installment of a three-part series on creating these custom Web controls in MC++ starts there.

Before you can do any work on custom Web controls, you should probably create an ASP.NET Web Form in which to display them. Custom Web controls don’t work on a standalone basis. Instead, they are implemented within a Web Form. To simplify things, I use a C# Web Form to house the MC++ custom Web controls created in this article. (In a future article, I’ll cover how to develop the actual ASP.NET Web application using only MC++, but if you can’t wait, my book Managed C++ and .NET Development shows you how in great detail.)

Prep Work

Open up Visual Studio .NET 2003 and create a new C# ASP.NET Web Application with the name CustomControls and then change the page layout to FlowLayout. Obviously, you can call it whatever you like in the future, and GridLayout page layout works fine as well.

Figure 1: Create a New C# ASP.NET Web Application Named CustomControls

I’ll use this Web Form shortly, but start working in Managed C++.

There is really nothing magical about custom Web controls. In fact, they are just standard Managed Classes within a .NET Class Library. So, go ahead and add a MC++ .NET Class Library called CustomControlsLib. (I put the library in the same directory structure as the Web application to make things easier to zip up later, but you can place it anywhere.)

Figure 2: Add a MC++ .NET Class Library Called CustomControlsLib

Once I have a Managed C++ .NET Class Library, I usually remove the extra files from the solution (resource files, resource.h, and ReadMe.txt). I find they just clutter up things. I normally would delete the CustomControlsLib.* files as well, but I’m going to leave them because I am going to use them for a little prep work.

The only advantage I see that C# and VB.NET have over MC++ when it comes to custom Web controls is that they offer templates. I level that playing field somewhat by creating a pair of code snippets and then putting them in the General Tab on the toolbox. When you create these snippets, just code them in the appropriate CustomControlLib file and then drag and drop the code onto the general tab of the toolbar. Once the code snippets are in the toolbar, rename them to something more appropriate.

List 1: CustomControlsLib.h

#pragma once

using namespace System;
using namespace System::Web::UI;
using namespace System::Web::UI::WebControls;
using namespace System::ComponentModel;

namespace CustomControlsLib
{
   [DefaultProperty("Text"),
   ToolboxData("<{0}:WebCustomControl runat=server></{0}
                    :WebCustomControl>")]
   public __gc class WebCustomControl :
                     public System::Web::UI::WebControls::WebControl
   {
   private
      String *text;

   public
      Bindable(true), Category("Appearance"), DefaultValue("")]
      __property String *get_Text();

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

   protected
      void Render(HtmlTextWriter *output);
   };
}

Listing 2: CustomControlsLib.cpp

#include "stdafx.h"

#include "CustomControlsLib.h"

using namespace CustomControlsLib;


String * WebCustomControl::get_Text()
{
   return text;
}

void WebCustomControl::set_Text(String *value)
{
   text = value;
}

void WebCustomControl::Render(HtmlTextWriter *output)
{
   output->Write(Text);
}

Believe it or not, one more step and you have created your first Managed C++ Custom Web Control. Notice above that CustomControlsLib.h references the System::Web::… namespaces. These require the System.Web assembly. Once you add that reference, compile everything.

Done! You now have your first custom Web control under your belt. Now, you need to add it to the CustomControls Web Form.

Because C# developers are so used to dragging and dropping stuff, I’ll not disappoint them and add your new custom Web control to the Web Forms Toolbox. First, select the WebForm1.aspx file. This will change the main menu to support ASP.NET development. In the Tools menu, select Add/Remove Toolbox items…; this will bring up the Customize Toolbox dialog box similar to Figure 3.

Figure 3: The Customize Toolbox Dialog Box

Within the dialog box, select the browse… button, navigate to the newly created CustomControlsLib.dll file, and open it. The dialog automatically selects all the custom Web controls found in the assembly. You can uncheck the controls you don’t want. Finally, click the OK button. When you open the Web Forms Toolbox, you’ll find the new control at the bottom.

Figure 4: The New Control at the Bottom of the Web Forms Toolbox

Now that the control is on the Toolbox, you can use it like any other Web Form control. Just drag and drop it onto your Web Form. Hmmm, it’s not much of a custom Web control is it?

What you are not noticing is the stuff happening in the background. When you drag and drop the control to the Web Form, a @ Register entry is added to the top of the Web Form (if it is the first time a control from the assembly is used):

<%@ Register TagPrefix="cc1" Namespace="CustomControlsLib"
             Assembly="CustomControlsLib" %>

And a control tag is added into the body of the Web Form, where the control is placed.

<cc1:WebCustomControl id="WebCustomControl1"
                      runat="server"></cc1:WebCustomControl>

Also, any properties in the control are placed within the Properties window. In this case, the only property is the Text property. If you change the Text property in the Properties window, the design window is also updated.

Okay, the prep work is almost done. The next thing that you will probably want to do is to replace the Cog wheel icon with something that reflects more accurately the functionality of the control.

Changing the icon is actually very easy once you know how. First, create a 16×16 bmp file that you want to represent your custom Web control. Then, name it <namespace>.<controlname>.bmp (for this example: CustomControlsLib.WebCustomControl.bmp). If you name it anything else, it will not work. Now, place the BMP file in the same directory as the custom Web control’s .h and .cpp files and add them to the project. Next, right-click the control’s project in the Solution explorer and select the properties menu item. This will open a Property Pages dialog box similar to Figure 5. Select the Linker|Input page. Next, change the Configuration drop-down box to All Configuration. If you don’t, the changes you make will be reflected only in the current configuration. Finally, in the Embed Managed Resource File, add the full name of the BMP file you previously added to the project.

Figure 5: Property Pages Dialog Box

Once you recompile the custom Web control, the icon automatically replaces the cog wheel—the next time you add it to the Toolbox. So, don’t panic if the cog wheel is still there after you compile. You first have to remove the only custom Web control and then replace it with the newly compiled one, as shown in Figure 6. Just select the control in the Toolbox and press Delete to remove the control.

Figure 6: The Newly Compiled Custom Web Control

The last prep work you’ll probably want to do is to change the auto-generated default TagPrefix in the @ Register entry from the generic cc1 to something more unique and descriptive.

This is done by simply adding the following two lines to your AssemblyInfo.cpp for the custom Web control:

using namespace System::Web::UI;
[assembly:TagPrefix("CustomControlsLib", "newprefix")];

Of course, you are going to have to change the namespace to that of the custom Web controls and change newprefix to something more appropriate. Just make sure the TagPrefix value abides by the standard variable naming format. If you have already dragged and dropped your custom control to your Web Form, the @ Register entry has already been added. Visual Studio .NET recognizes this and does not try to add a new one. So, to get your new tag to be used, you must delete the @ Register entry and the copy of the custom Web control from your Web Form’s HTML code and then drag a new copy of the custom Web control.

Once you have made the changes, the new version of the @ Registry is:

<%@ Register TagPrefix="newprefix" Namespace="CustomControlsLib"
             Assembly="CustomControlsLib" %>

And a control tag is:

<newprefix:WebCustomControl id="WebCustomControl1"
           runat="server"></newprefix:WebCustomControl>

All Prepped and Ready to Go

That’s enough prep work. Here’s what I’ve covered so far:

  1. I showed how to set up a project for a custom Web Control.
  2. I created a template for the control’s .h and .cpp files.
  3. I placed the new control on the toolbar.
  4. I showed how to change the default control icon and TagPrefix.

In the next installment of this article series, I’ll make some real custom Web controls, starting with Superclass custom Web controls and composite controls. Then, in the third installment, I’ll cover rendered custom Web controls.

Biography

Stephen Fraser has over 15 years of IT experience working for a number of consulting companies and smaller e-business companies. He has authored and co-authored .NET-related books, including the upcoming Managed C++ and .NET version 2.0 Development.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories