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.
|
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:
public class CountedButton : System.Windows.Forms.Button
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:
public CountedButton( )
While you are at it, change the filename from UserControl1 to CountedButton.cs or CountedButton.vb.
|
Override the OnPaint method to draw the number of times the button was clicked:
protected override void OnPaint (PaintEventArgs e) { if ( numClicks = = 0 ) this.Text = "Never been clicked"; else this.Text = "Clicked " + numClicks + " times"; base.OnPaint(e); }
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.
protected override void OnClick( EventArgs e ) { numClicks++; Invalidate( ); base.OnClick(e); }
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#)
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)
' 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.
|
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
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:
public int NumClicks { get { return numClicks; } set { numClicks = value; } }
Public Property numClicks( ) As Integer Get Return _numClicks End Get Set(ByVal Value As Integer) _numClicks = Value End Set End Property
|
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:
private void btnUpdate_Click(object sender, System.EventArgs e) { lblOut.Text = "The button was clicked " + countedButton1.NumClicks.ToString( ) + " times."; }
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.