Building Visual Components with C# .NET

Figure 1

Environment: Written in C# and Windows Forms for .NET. Compiled using VS7 (7.0.9466) and tested using Windows 2000 Professional and Windows XP Professional with the .NET Framework (1.0.3705).

Description

This article is an elementary introduction to writing visual components with the Microsoft .NET framework using C#. The application also demonstrates how to use properties in classes (a feature of the C# language), use of GDI+, the successor of GDI, create and lay out controls on a simple form, and handling events. The component contains two buttons; on pressing one of them, a figure is drawn (either a circle or a rectangle). The same result is obtained when changing the value of the propery Figure.

In the image at the top of the article you can see the result of the steps described above. The component area background is yellow to clearly delimitate it from the background of the form. The form contains a combo box which sets the property Figure of the component when the selection changes.

Creating the Project

Open Visual Studio .NET and from the menu File/New, choose Project. Select Visual C# Projects from the Project Types tree, click Windows Control Library, and type MyLibrary as the Name of the project; then click OK. The wizard will generate the source files and will open the Designer with the area of the User Control blank.

Let's take a look at the UserCotrl1.cs file, created by the wizard. Choose Solution Explorer from the View menu, if it is not already shown, right-click on the file UserControl1.cs, and choose View Code. The file contains the class UserControl1, included in the namespace MyLibrary. The UserControl1 class is derived from System.Windows.Forms.UserControl, which implements the basic functionability of a visual component. "User controls combine rapid control development with standard Windows Forms control functionality and the versatility created by adding custom properties and methods," VS .NET Documentation.

Editing the Control's GUI

Right-click UserControl1.cs in the Solution Explorer and choose View Designer. To enlarge the the surface of the control to 200x256, press F4 to view the Properties window and, in the Size node, set the Width and Height of the control.

Place two buttons on the surface of the control as seen below in Figure 2. Select the buttons from the Toolbox (select it from the View menu) and lay them on the control. Place a label under these buttons and name it labelFigure. Also, to easily distinguish the surface of the control from the background of the parent window (which we'll create later), select the cotrol and set value Info to field BackColor from the Properties window.

Figure 2

Set the Name of the buttons in the Properties window to btnCircle and btnRectangle and the Text of the buttons to Circle and Rectangle.

The Code

Let's create a Figure property for the client code to change the geometric form that the control draws. Switch to the code window and type the following code after the components declaration:

  public string Figure
  {
    get
    {
      return labelFigure.Text;
    }
    set
    {
      labelFigure.Text = value;
    }
  }

Notice that value is the default parameter of the set method.

Set the Figure property to Cicle in the constructor, after(!) InitializeComponent().

  this.Figure = "Circle";

The following code actually draws the two geometric forms:

// Draws a circle on the control surface
protected void DrawCircle(Graphics g)
{
  // create a pen
  Pen blackPen = new Pen(Color.Black, 1);
  // create a rectangle in which the circle will be drawn
  Rectangle rect = new Rectangle(20, 60, 150, 150);
  g.DrawEllipse(blackPen, rect);
}

// Draws a rectangle on the control surface
protected void DrawRectangle(Graphics g)
{
  // create a pen
  Pen blackPen = new Pen(Color.Black, 1);
  // create a rectangle in which the square will be drawn
  Rectangle rect = new Rectangle(20, 60, 150, 150);
  g.DrawRectangle(blackPen, rect);
}

Handling the messages

Switch to Designer and select the control's surface; open the Properties window and double-click the Paint message in the Events list to create the UserControl1_Paint method. You can also write another method by hand protected override void OnPaint(PaintEventArgs e) to handle this event. Enter this code in the method:

// Called when Paint message arise
private void UserControl1_Paint(object sender,
                System.Windows.Forms.PaintEventArgs e)
{
  Graphics g = e.Graphics;
  // Compare strings like in Java
  if (Figure.Equals("Circle"))
    DrawCircle(g);
  else if (Figure.Equals("Rectangle"))
    DrawRectangle(g);
}

Double-click the buttons to create the skeleton of the Click event hadlers and enter the following code:

// Handle for the click event on the Circle button
private void btnCircle_Click(object sender,
                             System.EventArgs e)
{
  Figure = "Circle";
}

// Handle for the click event on the Rectangle button
private void button1_Click(object sender, 
                           System.EventArgs e)
{
  Figure = "Rectangle";
}

One more thing before Testing the control in the set method for the Figure property: We should update the geometric form:

  set
  {
    labelFigure.Text = value;
    // Redraw the geometric form
    Refresh();
  }

Take a look at InitializeComponent() to see how event handlers are added to events. It's almost the same architecture as in Java. You can also see the code that initiazes the standard controls. Unfortunately, I had some problems with VS .NET reverse-engineering these lines, so I suggest you don't change it. You may have some problems when returning to the Design view; instead, use the Designer.

Creating the test application

Press CTRL+SHIFT+B to compile the solution and create MyLibrary.dll. If any error appears, correct it.

In the File menu, select Add project/New project.., select Windows Application, type UserControl1Test in the Name edit box from the Add New Project dialog, and click OK.

Select the Components tab in the Toolbox; right-click and choose Customize toolbox... In a few seconds, the Customize toolbox dialog appears. Select .NET Framework Components, click the Browse... button, and select MyLibrary.dll from MyLibrary\MyLibrary\bin\Debug folder. Click OK.

Click the newly added UserControl1 from the Toolbox and place it on the form. Right-click UserControl1Test in the Solution Explorer, and select Set as StartUp Project from the context menu. Run the application and click the buttons to change the drawn geometric form.

Click the user control in Form1 and go to the Figure field in the Properties window. You can see that the default value is Circle; enter Rectangle in this field, and the geometric form will change.

Just one more control on the form and we're done. Lay a ComboBox on the form (as seen at the top of the article), select it, and enter the values Circle and Rectangle in the String Collection Editor that shows when you press the button near Items in the Properties window. Set the DropDownStyle to DropDownList.

Double-click the combo box to create the event handler and type this code:

// handler for SelectedIndexChanged message on comboBox1
private void comboBox1_SelectedIndexChanged(object sender,
                                            System.EventArgs e)
{
  userControl11.Figure = comboBox1.Text;
}

Downloads

Download source - 16 Kb



Comments

  • Adding event from control to the application

    Posted by Legacy on 07/28/2002 12:00am

    Originally posted by: Olivier Debels


    This works fine but I was wondering how you could update the combobox in the test application when the control is updated (by pushing the buttons in the control).

    How do you generate an "event" coming from the control and how do you catch it in the application?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • On-demand Event Event Date: October 23, 2014 Despite the current "virtualize everything" mentality, there are advantages to utilizing physical hardware for certain tasks. This is especially true for backups. In many cases, it is clearly in an organization's best interest to make use of physical, purpose-built backup appliances rather than relying on virtual backup software (VBA - Virtual Backup Appliances). Join us for this webcast to learn why physical appliances are preferable to virtual backup appliances, …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds