Make a custom component in C#


[custom component]

There are a couple of ways that you can approach this problem. In this post, I’ll describe two: subclassing from Component and making a control that is invisible at runtime.

Subclassing From Component

To make a true component, simply make a class that inherits from the System.ComponentModel.Component class. If you’re using a newer version of Visual Studio, open the Project menu, select Add Component, enter a component name (I called this one MyComponent), and click Add.

If you’re using an older version of Visual Studio, then the Project menu may not have an Add Component command. In that case, simply create a new class and make it inherit from System.ComponentModel.Component.

To change the icon that the component displays in the Component Tray, add a ToolboxBitmap attribute and specify the name of the 16×16 pixel image file that the component should use.

You can include the image file in a couple of ways. For this example, I embedded the file in the project. To do that, open the Project menu, select Add Existing Item, select the file, and click Add. Then select the file in Project Explorer and set its Build Action property to Embedded Resource.

When you build the project, the component will add itself to the Form Designer’s Toolbox. Unfortunately, it won’t display its toolbox icon. (Yeah, I know.) To make it display its icon in the Toolbox, you must add it to the Toolbox manually.

To do that, right-click on the Toolbox and select Choose Items. Click the Browse button and select the compiled project that contains the component. (You may need to uncheck the component in the Choose Toolbox Items dialog first and then re-add the compiled project. This doesn’t seem to work very reliably, at least for me. Perhaps it works in newer versions of Visual Studio.)

The following code shows the example’s MyComponent class.

using System.ComponentModel;
using System.Windows.Forms;

namespace howto_custom_component
{
    [System.Drawing.ToolboxBitmap(typeof(MyComponent), "Small Smiley.png")]
    public class MyComponent : Component
    {
        public void SayHello()
        {
            MessageBox.Show("Hello", "MyComponent", MessageBoxButtons.OK);
        }
    }
}

In addition to the ToolboxBitmap attribute, this code defines a SayHello method that simply displays a message box.

Making a Control that is Invisible at Runtime

Another approach is to make a control that behaves sort of like a component. With this approach, the control displays itself on the form at design time but is invisible at runtime. (Sort of like a VB 6 component, if you can remember that far back.)

To do that, open the Project menu and select Add User Control. Enter a name for the control (I used the name Smiler) and click Add. Then, on the Control Designer, add any constituent controls that you want the custom component to contain.

To make the component display something at design time, set its BackgroundImage property to an image. Set its Size property to match the image’s size. In this example, I used a 32×32 pixel image, so I set the Size property to 32, 32.

Next, add code similar to the following to handle the control’s Resize event.

// Size the control to fit its background image.
private void Smiler_Resize(object sender, EventArgs e)
{
    Size = BackgroundImage.Size;
}

This code sets the control’s size to match that of its background image. When you add a Smiler to a form at design time, it will always have this size.

Next, add a Load event handler similar to the following to the control class.

// Hide the control at runtime.
private void Smiler_Load(object sender, EventArgs e)
{
    if (!DesignMode) Visible = false;
}

This method checks the component’s inherited DesignTime property to see if the control is running at design time or runtime. Those are the times for the form containing the control. When you place a control on a form, that’s design time. When you run the program, that’s runtime.

If the control is in runtime, the code sets its Visible property to false to hide it.

The example’s also defines the following SayHi method.

// Display a hello message box.
public void SayHi()
{
    MessageBox.Show("Hi", "Hi", MessageBoxButtons.OK);
}

This method simply displays a message box that says, “Hi.”

Using the Component

When you build the solution, the component or control should appear in the Form Designer’s Toolbox. You can then place them on the form as usual.

NOTE: When you download the example project, you must build it before the component and control will be usable.

The example program displays a button that executes the following code.

private void btnSayHi_Click(object sender, EventArgs e)
{
    smiler1.SayHi();
    myComponent1.SayHello();
}

This code calls a Smiler control’s SayHi method and then calls a MyComponent object’s SayHello method.

The left part of the picture at the top of this post you can see the form in the Form Designer. On the form, you can see the Smiler control named smiler1. Below the form, you can see the MyComponent component named myComponent1 in the Component Tray.

On the right side of the picture, you can see the form at runtime. Here the smiler1 control is invisible. (The MyComponent component is also invisible, but that’s less impressive. You would expect a component to be hidden at runtime.)

In the middle of the picture, you can see the smiler1 control’s dialog.

Download the example program to experiment with it and to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in controls and tagged , , , , , , , . Bookmark the permalink.

One Response to Make a custom component in C#

  1. Ello says:

    Thanks Rod for the example! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.