Lesson 2: Authoring Controls

Lesson 2: Authoring Controls

Windows Forms programming is based on controls. Controls allow you to encapsulate discrete units of functionality and provide a graphical representation of that functionality to the user. The .NET Framework provides a variety of tools and techniques to help you create custom controls for your applications. In this lesson, you will learn about the different types of controls you can create and the tools available to help you create them.

After this lesson, you will be able to

  • Describe the different types of user-authored controls

  • Explain how each type of user-authored control is created

  • Describe how to add properties, methods, and events to your controls

  • Describe how to create an inherited control

  • Describe how to create a user control

  • Describe how to create a custom control

Estimated lesson time: 45 minutes

In the .NET Framework, controls are specialized classes that include code for rendering a graphical interface. There are several possible sources for the controls you use in your applications. The controls included with Microsoft Visual Studio .NET provide a broad range of functionality and allow development of client applications with a rich array of features. You can also purchase controls from third-party developers to use in your applications, or you can use existing ActiveX controls. Third-party controls can provide functionality not found in the .NET Framework set of controls. Additionally, if you need a control with a set of features unavailable in the .NET Framework controls or in the third-party controls, you can create your own controls.

Overview of Control Authoring

All controls in the .NET Framework inherit either directly or indirectly from the base class Control. This class provides all the basic, low-level functionality that a control needs. For example, the Control class provides logic for handling user input through keyboard and mouse interaction. It provides logic for interacting with Windows. And it further provides a set of properties, methods, and events that are common to all controls. It does not include logic that creates the unique functionality of the control, nor does it contain code for graphically rendering the control.

There are three basic techniques for creating a control. You can

  • Inherit from an existing control.

  • Inherit from UserControl.

  • Inherit from Control.

Inheriting from an Existing Control

Inheriting from an existing control is the easiest and least time-consuming way to develop a new control. The new control contains all the functionality represented by the base control but can also serve as a base for new functionality. An inherited control also inherits the visual representation of the base control.

You should choose this technique if you need to replicate most or all of the functionality of an existing Windows Forms control but want to add custom functionality as well. You should also use this technique if you want to retain the functionality of an existing Windows Forms control but want to provide a new look and feel.

Most Windows Forms controls can be used as a base class for inheritance unless they are specified as NotInheritable (sealed). For example, you could create a TextBox control with built-in validation or a PictureBox control that allows the user to select filters to apply to the images.

You can also use inheritance to create controls that have the same functionality as the base control but have a different appearance, such as a Button that is round instead of square. Thus, a control that extends Button will look just like a regular Button no additional code is needed to render the new control but you can implement code to alter its appearance if you want.

You should not inherit from an existing Windows control if you need radically different functionality.

Inheriting from UserControl

Sometimes, a single control does not contain all the functionality you need. For example, you might want a control that you can bind to a data source to display a first name, a last name, and a phone number, each in a separate TextBox. Although it is possible to implement this logic on the form itself, it might be more efficient to create a single control that contains multiple text boxes, especially if this configuration is needed in several different applications. Controls that contain multiple Windows Forms controls bound together as a single unit are called user controls.

You can create a user control (sometimes called a composite control) by inheriting from the UserControl class. The UserControl class provides a base of functionality that you can build on by adding properties, methods, events, and other controls. The UserControl designer allows you to add other Windows Forms controls to the design surface and create code to implement custom functionality. The result is a user-designed control made up of multiple Windows Forms controls that act as a single coherent unit.

Limited design of the user control visual interface is possible, but most of the visual modifications you can make consist of simply configuring and positioning the constituent controls.

Creating a user control can be relatively simple task or complex, depending on the level of functionality the control must expose. You should consider creating a user control if you need to combine the functionality of multiple existing controls and add custom logic to the unit.

Inheriting from Control

If you require a richer visual interface or functionality that is not achievable with a user control or an inherited control, you can create a custom control. Custom controls derive from Control, the base class for all controls. The Control class provides a lot of the functionality common to all controls, such as interacting with the mouse and common events, such as Click. The Control class also provides a set of properties that are useful for controls, such as Font, ForeColor, BackColor, Visible, and so on. The Control class does not, however, provide any specific control functionality. All control logic specific to the control functionality must be programmed. Additionally, although the Control class provides many properties that support a visual depiction, the developer must program all the code for creating the control s visual representation. These steps can be time-consuming. You should consider creating a custom control only when you need a richness of form or functionality that cannot be supplied by an inherited control or a user control.

Adding Members to Controls

You can add properties, methods, fields, and events to your controls in the same manner as you add members to a class. You can create member declarations with any appropriate access level, and the form that hosts the control will be able to call any public members of that control.

Public properties that are added to controls are automatically displayed in the Properties window at design time. Thus they can be edited and configured by any user of your application. If you do not want a property to be displayed in the Properties window, you must mark the property with the Browsable attribute and specify false. The following code example shows how to mark a property so that it will not be displayed in the Properties window at design time:

Visual Basic .NET

<System.ComponentModel.Browsable(False)> _ Public Property StockNumber() As Integer ' Property Code omitted End Property

Visual C#

[System.ComponentModel.Browsable(false)] public int StockNumber { // Property code omitted }

Creating an Inherited Control

An inherited control contains all the functionality provided by its base class and can serve as a base for new functionality as well. You create an inherited control by specifying a Windows Forms control as the base class for your control. The new control retains the same look and feel as the base control. The following code example demonstrates how to create a control that inherits from Button:

Visual Basic .NET

Public Class myButton Inherits System.Windows.Forms.Button ' Additional code omitted End Class

Visual C#

public class myButton : System.Windows.Forms.Button { // Additional code omitted }

Adding New Functionality to an Inherited Control

One reason to create an inherited control is to add functionality to an existing Windows Forms control. You can either add new functionality to your control or you can override members exposed by the base class. For example, suppose you wanted to create a text box that only accepts numbers as user input. You might implement this control by overriding the OnKeyPress method, as shown in the following code example:

Visual Basic .NET

Public Class NumberBox Inherits System.Windows.Forms.TextBox Protected Overrides Sub OnKeyPress(ByVal e As KeyPressEventArgs) If Char.IsNumber(e.KeyChar) = False Then e.Handled = True End If End Sub End Class

Visual C#

public class NumberBox : System.Windows.Forms.TextBox { protected override void OnKeyPress(KeyPressEventArgs e) { if (char.IsNumber(e.KeyChar) == false) e.Handled = true; } }

Creating a New Appearance for an Existing Control

Another reason you might create an inherited control is to alter the appearance of an existing Windows Forms class. You can create a new look and feel for an existing control by overriding the OnPaint method and providing your own rendering code. If you want to change the shape of the control, you must set the control s Region property in the OnPaint method. A Region is a class that describes a regular or irregular region of the screen similar to a GraphicsPath. A Region can be created from a GraphicsPath. You can thus create a GraphicsPath to represent the shape of your control and then assign the control to a new Region based on the GraphicsPath. The following code example demonstrates how to create a button that renders as a string of text:

Visual Basic .NET

Public Class WowButton Inherits System.Windows.Forms.Button Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs) Dim myPath As New Drawing2D.GraphicsPath() ' This line sets the GraphicsPath to render a 72 point string ' in the FontFamily and the FontStyle of the control. myPath.AddString("Wow!", Font.FontFamily, Font.Style, 72, New _ PointF(0, 0), StringFormat.GenericDefault) ' Creates a new Region from the GraphicsPath Dim myRegion As New Region(myPath) ' Assigns the new Region to the Region property of the control Me.Region = myRegion End Sub End Class

Visual C#

public class WowButton : System.Windows.Forms.Button { protected override void OnPaint(PaintEventArgs pe) { System.Drawing.Drawing2D.GraphicsPath myPath = new System.Drawing.Drawing2D.GraphicsPath(); // This line sets the GraphicsPath to render a 72 point string // in the FontFamily and the FontStyle of the control. In C#, // you must explicitly convert Font.Style to an int. myPath.AddString("Wow!", Font.FontFamily, (int)Font.Style, 72, new PointF(0, 0), StringFormat.GenericDefault); // Creates a new Region from the GraphicsPath Region myRegion = new Region(myPath); // Assigns the new Region to the Region property of the control this.Region = myRegion; } }

Note that the WowButton is not just a rectangular button with a transparent background and large text. It is a Button shaped like the letters in the word Wow! If you want to click it, you must click within the region bounded by those letters. Thus, you can change the shape of common controls to provide custom UI elements.

NOTE
Some controls, such as TextBox, are drawn by the form they exist on, not by the controls themselves. For these controls, the Paint event is never raised; thus, custom-rendering code is never called.

To create an inherited control

  1. Create a class that inherits the control on which you want to base your control.

  2. Add any custom functionality or code to render visual elements.

Creating a User Control

User controls represent a way to combine custom functionality, standard Windows Forms controls, and rapid development. A user control consists of one or more Windows Forms controls bound together in a single unit. The subordinate controls that make up a user control, called constituent controls, can be added to the user control designer at design time. You can add a user control to your project by choosing Add User Control from the Project menu. Figure 7.1 shows the UserControl designer with two constituent buttons and a TextBox.

figure 7-1 the usercontrol designer.

Figure 7-1. The UserControl designer.

You can write custom functionality to respond to events raised by the constituent controls. For example, suppose you want to create a user control consisting of two constituent TextBox controls and a constituent Label control, and you want the label to automatically display the sum of the numeric values in each TextBox as the values are changed. You could implement this functionality by overriding the OnKeyPress method in each constituent TextBox, as shown in this example:

Visual Basic .NET

' You would also add a similar method for the KeyPress event of ' TextBox2 Private Sub TextBox1_KeyPress(ByVal Sender As Object, ByVal e As _ KeyPressEventArgs) Handles TextBox1.KeyPress ' Verifies that a number was pressed If Char.IsNumber(e.KeyChar) = False Then e.Handled = True End If Label1.Text = (Integer.Parse(TextBox1.Text) + _ Integer.Parse(TextBox2.Text)).ToString() End Sub

Visual C#

// You would also add a similar method for the KeyPress event of // TextBox2 protected override void OnKeyPress(object sender, KeyPressEventArgs e) { // Verifies that a number was pressed if (char.IsNumber(e.KeyChar) == false) e.Handled = true; Label1.Text = (int.Parse(TextBox1.Text) + int.Parse(TextBox2.Text)).ToString(); }

When you build and use a user control with Visual Studio .NET 2002, the constituent controls are treated as Private (private) by default. Thus, there is no way for future developers who might use your constituent controls to alter their properties, such as color, shape, or size. If you want to allow other developers to change the properties of constituent controls, you must selectively expose them through the properties of the user control. For example, consider a user control that contains a Button named Button1. If you want to expose the BackColor property of Button1, you do so by wrapping it in a property declaration for your user control, as shown in the following code example:

Visual Basic .NET

' This property declaration is in the user control class Public Property ButtonColor() As Color Get Return Button1.BackColor End Get Set(ByVal Value As Color) Button1.BackColor = Value End Set End Property 

Visual C#

public Color ButtonColor { get { return Button1.BackColor; } set { Button1.BackColor = value; } }

You can also expose a constituent control entirely by changing the Modifiers property. This property is only available in the Properties window at design time it does not exist at run time. The Modifiers property can be set to any access level and has the effect of setting the constituent control to that access level.

NOTE
In Visual Basic .NET 2003, constituent controls are declared by default with Friend access, and thus can be accessed by the owning form. In Visual C# 2003, the access level remains private.

To create a user control

  1. Create a class that derives from the UserControl base class.

  2. Add Windows Forms controls to the UserControl designer, and configure them appropriately.

  3. Expose any constituent control properties.

  4. Write any custom functionality for your user control.

Creating a Custom Control

As noted earlier, custom controls provide the highest level of configurability and customization, but they are also the most time-consuming to develop. Because the Control class provides no base visual representation, you are obliged to write the code to render the control s visual representation. In cases where a particularly complex visual representation is desired, this can be the most time-intensive part of the control development process.

The process of rendering a control to the drawing surface is called painting. When the control receives instruction that it needs to be rendered, it raises the Paint event. This causes any handlers for the Paint event to be executed. In the Control class, the default handler for the Paint event is the OnPaint method.

The OnPaint method receives a single argument: an instance of PaintEventArgs. The PaintEventArgs class contains information about the drawing surface available to the control. Two notable members of PaintEventArgs are Graphics and ClipRectangle.

The Graphics member of PaintEventArgs is a Graphics object that represents the control s drawing surface. This reference to a Graphics object is used to render the visual representation of the control. The ClipRectangle member is a rectangle that represents the area available for the control to draw in. When the control is first drawn, the ClipRectangle represents the bounds of the entire control. At times, regions of the control might be covered by other controls and portions of the visual representation might be obscured. When the control is redrawn, the ClipRectangle only represents the region that needs to be redrawn. Thus, the ClipRectangle should not be used to determine the size of the control. Instead, you should use the Size property to access the size of a custom control.

By default, coordinates are measured relative to the upper-left corner of the control, which is assumed to be point (0,0). Coordinate points are measured in pixels by default. The following code example shows a very simple OnPaint method that renders the custom control as a single red ellipse:

Visual Basic .NET

' This example assumes Imports System.Drawing Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs) Dim aBrush As New SolidBrush(Color.Red) Dim clientRectangle As New Rectangle(New Point(0,0), Me.Size) pe.Graphics.FillEllipse(aBrush, clientRectangle) End Sub

Visual C#

// This example assumes using System.Drawing protected override void OnPaint(PaintEventArgs e) { Brush aBrush = new SolidBrush(Color.Red); Rectangle clientRectangle = new Rectangle(new Point(0,0), this.Size); e.Graphics.FillEllipse(aBrush, clientRectangle); }

When a control is resized, the ClipRectangle is automatically resized but the control is not necessarily redrawn. If you want the control to be redrawn whenever it is resized, you must use the Control.SetStyle method to set the ResizeRedraw flag to true. The call to the SetStyle method should be placed in the constructor. The following code example demonstrates how to use the SetStyle method:

Visual Basic .NET

SetStyle(ControlStyles.ResizeRedraw, True)

Visual C#

SetStyle(ControlStyles.ResizeRedraw, true);

You can manually cause the control to redraw at any time by calling the Refresh method, as follows:

Visual Basic .NET

Refresh()

Visual C#

Refresh();

To create a custom control

  1. Create a class that derives from the Control base class.

  2. Add code to render the control in the OnPaint method.

  3. Add any custom functionality to your control.

Lesson Summary

  • All controls inherit either directly or indirectly from the base class Control. The Control class provides keyboard and pointer functionality as well as a set of common control properties.

  • There are three primary approaches to control authoring: inheriting from an existing control, creating a user control, and creating a custom control.

  • You can create an inherited control by inheriting from an existing Windows Forms control. The new control has the same visual representation and functionality as the base control.

  • A user control encapsulates one or more Windows Forms controls and inherits from the UserControl class. Constituent controls are private by default and cannot be accessed at run time unless specifically exposed by changing the Modifiers property.

  • A custom control is the most time-consuming approach to control development. Custom controls inherit from the Control class without graphic representation. In addition to writing code that represents the functionality of the control, you must provide code to paint the control.



MCAD(s)MCSD Self-Paced Training Kit(c) Developing Windows-Based Applications With Microsoft Visual Basic. Net a[.  .. ]0-316
MCAD(s)MCSD Self-Paced Training Kit(c) Developing Windows-Based Applications With Microsoft Visual Basic. Net a[. .. ]0-316
ISBN: 735619263
EAN: N/A
Year: 2003
Pages: 110

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net