Introduction
While writing a little tool in C# which I will present here at CodeProject
some time in the future I needed a TextBox Control with the ability of input
validation. Because I didn't find a control like this written in C# here at
CodeProject I wrote my own and try to present it with my first article!
Capabilities
Right now this control performs basic input validation of the characters
entered by the user by comparing them to a string containing valid or invalid
characters.
Description
The ValidatingTextBox class resides in the TextBoxExtension.dll assembly in
the TextBoxExtension namespace.
The behaviour of the ValidatingTextBox control is controlled by three
properties:
public string ValidationString{get;set;}
This property gets or sets the string to validate the input against.
public ValidationType ValidationMode{get;set;}
This property controls wether the characters in the provided ValidationString
contain the valid chars or the invalid chars.
public bool CaseSensitiveValidation{get;set;}
If this property is set to true uppercase letters are treated differently than
lowercase ones.
Events
Depending on user action various events are fired by the control:
Property-changed events:
public event EventHandler ValidationModeChanged;
This event gets fired whenever the ValidationMode Property has been changed.
public event EventHandler ValidationStringChanged;
This event gets fired whenever the ValidationString changed.
<code>public event EventHandler CaseSensitiveValidationChanged;
Whenever the case sensitivity of the validation is altered this event gets
fired.
Validation Events:
public event EventHandler ValidationSuccessful;
Whenever a character input has been successfully validated this event gets
fired.
public event CharValidationFailedEventHandler CharValidationFailed;
public class CharValidationFailedEventArgs : EventArgs
{
public CharValidationFailedEventArgs(ValidationType mode, char failed)
{
currentValidationMode = mode;
failedChar = failed;
}
private char failedChar;
private ValidationType currentValidationMode;
public char FailedChar
{
get
{
return failedChar;
}
}
public ValidationType CurrentValidationMode
{
get
{
return currentValidationMode;
}
}
}
public delegate void CharValidationFailedEventHandler(object sender,
CharValidationFailedEventArgs e);
This event is raised whenever a char failed validation. The event handler
presents the char that failed validation (f.e. for error reporting) along with
the current validation mode.
The validation process takes place in an override of the WndProc
method of
the base class:
In this override WM_CHAR
messages are intercepted and the method of the base
class is only called when a valid char has been entered. Non displayable
keyboard input like Tab, Delete and Return are always treated as valid:
private const int WM_CHAR = 0x0102;
private const int VK_BACK = 0x08;
private const int VK_TAB = 0x09;
private const int VK_CLEAR = 0x0C;
private const int VK_RETURN = 0x0D;
protected override void WndProc(ref Message message)
{
if(message.Msg == WM_CHAR)
{
char cTest = (char)message.WParam;
string sTest;
string sValidate;
if(caseSensitiveValidation)
{
sTest = cTest.ToString();
sValidate = validationString;
}
else
{
sTest = cTest.ToString().ToUpper();
sValidate = validationString.ToUpper();
}
switch(cTest)
{
case (char)VK_BACK:
case (char)VK_CLEAR:
case (char)VK_RETURN:
case (char)VK_TAB:
base.WndProc(ref message);
if(CharValidationSuccessful!=null)
{
EventArgs args = new EventArgs();
CharValidationSuccessful(this,args);
}
return;
}
if(validationMode == ValidationType.ValidateAgainstValid)
{
if(sValidate.IndexOf(sTest)<0)
{
if(CharValidationFailed!=null)
{
CharValidationFailedEventArgs args =
new CharValidationFailedEventArgs(validationMode,cTest);
CharValidationFailed(this,args);
}
return;
}
else
{
base.WndProc(ref message);
if(CharValidationSuccessful!=null)
{
EventArgs args = new EventArgs();
CharValidationSuccessful(this,args);
}
return;
}
}
else
{
if(sValidate.IndexOf(sTest)<0)
{
if(CharValidationSuccessful!=null)
{
EventArgs args = new EventArgs();
CharValidationSuccessful(this,args);
}
base.WndProc(ref message);
return;
}
else
{
if(CharValidationFailed!=null)
{
CharValidationFailedEventArgs args =
new CharValidationFailedEventArgs(validationMode,cTest);
CharValidationFailed(this,args);
}
return;
}
}
}
else
{
base.WndProc(ref message);
}
}
If you have to revalidate the content of the control you can call the
public bool RemoveInvalidChars(){...}
method of the control and all invalid characters will be removed. This
function never removes linefeed, carriage return or tabs. It returns true if
any chars have been removed.
The sample project for this article lets you play around with the features of
this control. You can add this control to your toolbox by right clicking on the
toolbox and selecting customize (hope that's how it is called as I have the
german version of VS .NET). Then you can add the assembly containing my control
to the list of .NET assemblies - et voila. Please let me know if you find a bug
or think that this control is useful.