Specializing an Existing Control

You'll create a customized button class that keeps track of how often it has been clicked. To begin, open a new project in Visual Studio .NET. In the Project Type window, choose your language of choice, and in the Templates window, choose Windows Control Library. Be sure to set an appropriate location, and name the library CountedControl.

This example is similar to a custom control demonstrated in Programming ASP.NET, but there are significant differences in how custom controls are created for use with Windows Forms.

You are placed in the designer for a user control. That isn't quite what you want (you'll be creating a user control in the next example), but it isn't a problem. Right-click on the form and choose View Code. Modify the class name to CountedButton and the base class from UserControl to Button:

figs/csharpicon.gif

public class CountedButton : System.Windows.Forms.Button

figs/vbicon.gif

Public Class CountedButton
 Inherits System.Windows.Forms.Button

In C#, you must also modify the constructor so it has the same name as the class:

figs/csharpicon.gif

public CountedButton( )

While you are at it, change the filename from UserControl1 to CountedButton.cs or CountedButton.vb.

When you change the base type from UserControl to Button, Visual Studio .NET will no longer use the Forms Designer in Design view. You'll add to the new derived button type entirely through code.

Override the OnPaint method to draw the number of times the button was clicked:

figs/csharpicon.gif

protected override void OnPaint (PaintEventArgs e)
{
 if ( numClicks = = 0 )
 this.Text = "Never been clicked";
 else
 this.Text = "Clicked " + numClicks + " times";
 
 base.OnPaint(e);
}

figs/vbicon.gif

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
 If numClicks = 0 Then
 Me.Text = "Never been clicked"
 Else
 Me.Text = "Clicked " & numClicks & " times"
 End If
 MyBase.OnPaint(e)
End Sub

Finally, override the on-click method to update the number of clicks, and invalidate the button so it will be repainted.

figs/csharpicon.gif

protected override void OnClick( EventArgs e )
{
 numClicks++;
 Invalidate( );
 base.OnClick(e);
}

figs/vbicon.gif

Protected Overrides Sub OnClick(ByVal e As EventArgs)
 numClicks = numClicks + 1
 Invalidate( )
 MyBase.OnClick(e)
End Sub

That's all there is to it! Build your control, and you are ready to test it. The complete source code for the custom control in C# is shown in Example 17-1 and the VB.NET version is shown in Example 17-2.

Example 17-1. Custom derived control (C#)

figs/csharpicon.gif

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
 
namespace CountedButtonCS1
{
 // change the base class to button
 public class CountedButton : System.Windows.Forms.Button
 {
 private System.ComponentModel.Container components = null;
 private int numClicks = 0; // keep track of number of clicks
 
 public CountedButton( )
 {
 InitializeComponent( );
 }
 
 // override OnPaint to display the number of clicks
 protected override void OnPaint (PaintEventArgs e)
 {
 if ( numClicks = = 0 )
 this.Text = "Never been clicked";
 else
 this.Text = "Clicked " + numClicks + " times";
 
 base.OnPaint(e);
 }
 
 // when the button is clicked update the counter
 // and invalidate the control
 protected override void OnClick( EventArgs e )
 {
 numClicks++;
 Invalidate( );
 base.OnClick(e);
 }
 
 
 /// 

/// Clean up any resources being used. ///

protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose( ); } base.Dispose( disposing ); } #region Component Designer generated code #endregion } }

Example 17-2. Custom derived control (VB.NET)

figs/vbicon.gif

' change the base class to button 
Public Class CountedButton
 Inherits System.Windows.Forms.Button
 
 
 ' keep track of number of clicks
 Private numClicks As Integer = 0
 
 Public Sub New( )
 MyBase.New( )
 InitializeComponent( )
 End Sub
 
 ' override OnPaint to display the number of clicks
 Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
 If numClicks = 0 Then
 Me.Text = "Never been clicked"
 Else
 Me.Text = "Clicked " & numClicks & " times"
 End If
 MyBase.OnPaint(e)
 End Sub
 
 ' when the button is clicked update the counter
 ' and invalidate the control
 Protected Overrides Sub OnClick(ByVal e As EventArgs)
 numClicks = numClicks + 1
 Invalidate( )
 MyBase.OnClick(e)
 End Sub
 
#Region " Windows Form Designer generated code "
#End Region
End Class

17.1.1 Testing the Control

Of course, you can't just "run" a control; you need a container, such as a form, within which to test the control. Create a new Windows project in your language of choice and add a reference to the control project. To do so from within Visual Studio .NET, right-click on References and choose Add Reference. Click on the Projects tab, and then click the Browse button. Navigate to the dll you created for your control, and double-click on it. Then click OK to close the Add Reference dialog.

You can add your control to your toolbox by right-clicking on the toolbox and choosing Customize Toolbox. Choose the .NET Framework Components tab, and then click the Browse button. Navigate to and double-click on your dll; the control appears at the bottom of your toolbox.

You can create your control in one language (e.g., C# or VB.NET) and your test program in another.

Double-click on the control to add it to the form, and size it to display the full message. Run the test program and click on the button. The result, shown in Figure 17-1, is that the button keeps track of how often it is clicked.

Figure 17-1. The CountedButton control

figs/pnwa_1701.gif

17.1.2 Adding Properties

One powerful use for custom controls is to expose custom properties. You might derive from the Button class only to expose new and interesting properties to your clients. In the next example, you'll modify your CountedButton class to add a property that reveals how often the button has been clicked.

The change to the control is almost trivial. Just add a property to the control to provide access to the number of times the button was clicked:

figs/csharpicon.gif

public int NumClicks
{
 get { return numClicks; }
 set { numClicks = value; }
}

figs/vbicon.gif

Public Property numClicks( ) As Integer
 Get
 Return _numClicks
 End Get
 Set(ByVal Value As Integer)
 _numClicks = Value
 End Set
End Property

Because I wanted the property to be named numClicks, I had to change the private field to _numClicks (note the underscore). VB.NET is case insensitive, so you can't use the idiom common in C# of naming the field with a lowercase letter and the property with an uppercase letter.

You can use this property in your test program. Add a label (named lblOut) and a button (named btnUpdate) to your form. Add an event handler for the button to update the label based on the numClicks property:

figs/csharpicon.gif

private void btnUpdate_Click(object sender, System.EventArgs e)
{
 lblOut.Text = 
 "The button was clicked " + 
 countedButton1.NumClicks.ToString( ) + 
 " times.";
}

figs/vbicon.gif

Private Sub btnUpdate_Click( _
 ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles btnUpdate.Click
 lblOut.Text = _
 "The button was clicked " & _
 CountedButton1.numClicks.ToString( ) & _
 " times."
End Sub

The key line of code is shown in bold. Determine how many times the button was pressed by accessing its numClicks property.





Programming. NET Windows Applications
Programming .Net Windows Applications
ISBN: 0596003218
EAN: 2147483647
Year: 2003
Pages: 148
Simiral book on Amazon

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