Browse DevX
Sign up for e-mail newsletters from DevX


Customize and Extend Windows Forms Controls : Page 2

Everybody who writes native Windows applications knows that the Windows Forms controls provided by Microsoft are a great time-saver for oft-used interface components such as text boxes and drop-down lists. But sometimes we need a reusable form control that does things Microsoft hasn't pre-built for us. Learn to extend existing Windows Forms controls with custom functions that will save you time.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Extending Windows Forms Controls
Using Visual Studio 2005, create a new Windows application and name it WindowsControls. This Windows application project will act as the host for the controls that you will be extending shortly.

Now, add a new Class Library project (File | Add | New Project…) to the current solution and name the project EnhancedTextBox.

As you are going to extend a Windows Forms control in this project (specifically the TextBox control), add a reference to System.Windows.Forms (right-click on the EnhancedTextBox project name in Solution Explorer and select Add Reference…).

Import the following namespaces:

Imports System.Windows.Forms Imports System.ComponentModel

Next, define the following enumerations (in bold) for the different types of casings, filters, and the different levels of precisions:

Imports System.Windows.Forms Imports System.ComponentModel Public Enum Cases Mixed UpperOnly LowerOnly End Enum Public Enum FilterTypes None IntegerNumeric DecimalNumeric AlphabetsOnly Alphanumeric End Enum Public Enum Precisions None OneDecimal TwoDecimal ThreeDecimal End Enum

And since you are extending the TextBox control, you need to inherit the EnhancedTextBox class from System.Windows.Forms.TextBox:

Public Class EnhancedTextBox Inherits System.Windows.Forms.TextBox

Declaring the Member Variables
You can now declare the member variables to store the filter type, casing, precision, as well as the regular expression as set by the user. Also, define an event so that when the validation fails, the user of the control can react appropriately:

<DefaultEvent("Err")> _ Public Class EnhancedTextBox Inherits System.Windows.Forms.TextBox '---member variables for filtering--- Private _filterType As FilterTypes = FilterTypes.None Private _casing As Cases = Cases.Mixed Private _precision As Precisions = Precisions.None '---member variables for regular expression validation--- Private _regex As String Private _regexErrMsg As String '---event handler for error--- <Category("Custom Properties"), _ DescriptionAttribute("Error event handler.")> _ Public Event Err(ByVal str As String)

Notice that I have marked the class with a DefaultEventAttribute that specifies the Err as the default event handler. I have also marked the Err event with the CategoryAttribute to associate it with the Custom Properties category in the Properties window (you will see this in action later). The DescriptionAttribute specifies the description for this event.

Declaring the Properties
You will next declare the various properties that allow the user to control the types of filter, precisions, and casing they want, as well as enter the regular expression to use for custom validation.

The Precision property specifies the number of decimal places with which to format the text input:

'---property for setting precision--- <Category("Custom Properties"), _ DescriptionAttribute("Number of decimal places.")> _ Public Property Precision() As Precisions Get Return _precision End Get Set(ByVal value As Precisions) _precision = value End Set End Property

The EnforceCasing property indicates if the character entered should automatically be converted to upper or lower casing:

'---property for enforcing casing--- <Category("Custom Properties"), _ DescriptionAttribute("Specifies if the characters " & _ "typed need to be converted to the specified case.")> _ Public Property EnforceCasing() As Cases Get Return _casing End Get Set(ByVal value As Cases) _casing = value End Set End Property

The FilterType property specifies the types of characters allowed for entry:

'---property for setting filter types--- <Category("Custom Properties"), _ DescriptionAttribute("Specifies the type of filter to apply.")> _ Public Property FilterType() As FilterTypes Get Return _filterType End Get Set(ByVal value As FilterTypes) _filterType = value End Set End Property

The RegularExpression property allows the user to set the regular expression to be used for custom validation:

'---property for setting the regular expression--- <Category("Custom Properties"), _ DescriptionAttribute("Regular expression for custom validation.")> _ Public Property RegularExpression() As String Get Return _regex End Get Set(ByVal value As String) _regex = value End Set End Property

And finally, the RegularExpressionErrorMessage property allows the user to specify the error message to display in a balloon should the regular expression validation fail:

'---property for error message to display if regular expresson ' validation fails--- <Category("Custom Properties"), _ DescriptionAttribute("Error message for regular expression " & _ "validation.")> _ Public Property RegularExpressionErrorMessage() As String Get Return _regexErrMsg End Get Set(ByVal value As String) _regexErrMsg = value End Set End Property

Servicing the Events
The final step is to service the various events associated with the TextBox control. To ensure that users can enter only the characters specified by the filter, you can service the KeyPress event of the TextBox control. The KeyPress event is fired whenever the user presses a key when the focus is on the TextBox control. This is the event to service so that only the allowed characters/digits are allowed to be shown in the TextBox control. The code for the KeyPress event is shown in Listing 1.

Here, you check for various types of characters that the user may enter. If an invalid character is detected, the e.Handled property is set to True and the character will not be added to the TextBox. The IsControl() method checks to see if a character entered is a control character (such as Tab, Carriage Return, BackSpace, etc). It is important that you check for control characters. Why? One good example is the BackSpace character. If the BackSpace character is ignored in the KeyPress event, then the user might not be able to erase a character entered in a TextBox control by using the BackSpace key. That would be bad user interface design.

While servicing the KeyPress event can prohibit users from entering illegal characters, you still need to do some more work in another event—the LostFocus event. The LostFocus event is fired when the focus is transferred from the TextBox control to somewhere else, such as pressing the Tab key to navigate to the next control.

A very important task you need to perform in this event is to validate the content of the TextBox control. This is because illegal characters can still seep into the control by methods other than direct entry through the keyboard; a user could assign the value of the TextBox control programmatically or paste (Ctrl-V) illegal characters into a TextBox control. For example, if you set a TextBox control with the IntegerNumeric filter, you are still able to programmatically assign a decimal numeric value to it through code. In this case, the KeyPress event cannot be used to restrict the assignment. Hence, in the LostFocus event you need to perform the various types of validation to ensure that the value in the TextBox control conforms to the specified filter. The code for the LostFocus event is shown in Listing 2.

The ShowErrorBalloon() method displays a message in a balloon using the ToolTip control:

Public Sub ShowErrorBalloon(ByVal str As String) Dim toolTip1 As New ToolTip With toolTip1 .IsBalloon = True .Show(str, Me, 10, -40, 2000) End With End Sub

Thanks for your registration, follow us on our social networks to keep up-to-date