|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
OverviewThis is a simple extension/restriction of the LanguageThe source code is in C#, .NET 2.0, VS2008. I've included the compiled DLL so VB users can use this control. What I haven't doneI haven't added any range or bounds control - it's a text box, not an int/double/decimal... box. There is no support for number separators, currency symbols, or even the - sign. They weren't required for the implementation I needed. If you want to add them, it shouldn't be too difficult. Surely this is simple, you just...That's what I thought too, until about two minutes into coding this! There's actually quite a lot that we do all the time with the text box, but never give it a second thought. As well as digits, we need to allow edit key combinations and navigation/selection keys and combinations. Pasting can be done either by keyboard or by mouse actions, so handling key events for this isn't sufficient. The codeThe interesting parts of the code are in the overridden OnKeyDownI've simply built protected override void OnKeyDown(KeyEventArgs e)
{
bool result = true;
bool numericKeys = (
((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) ||
(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
&& e.Modifiers != Keys.Shift);
bool ctrlA = e.KeyCode == Keys.A && e.Modifiers == Keys.Control;
bool editKeys = (
(e.KeyCode == Keys.Z && e.Modifiers == Keys.Control) ||
(e.KeyCode == Keys.X && e.Modifiers == Keys.Control) ||
(e.KeyCode == Keys.C && e.Modifiers == Keys.Control) ||
(e.KeyCode == Keys.V && e.Modifiers == Keys.Control) ||
e.KeyCode == Keys.Delete ||
e.KeyCode == Keys.Back);
bool navigationKeys = (
e.KeyCode == Keys.Up ||
e.KeyCode == Keys.Right ||
e.KeyCode == Keys.Down ||
e.KeyCode == Keys.Left ||
e.KeyCode == Keys.Home ||
e.KeyCode == Keys.End);
if (!(numericKeys || editKeys || navigationKeys))
{
if (ctrlA)
// Do select all as OS/Framework
// does not always seem to implement this.
SelectAll();
result = false;
}
if (!result) // If not valid key then suppress and handle.
{
e.SuppressKeyPress = true;
e.Handled = true;
if (ctrlA) { } // Do Nothing!
else
OnKeyRejected(new KeyRejectedEventArgs(e.KeyCode));
}
else
base.OnKeyDown(e);
}
CheckPasteValidWhen a paste message is received, it's caught in the overridden private PasteEventArgs CheckPasteValid()
{
// Default values.
PasteRejectReasons rejectReason = PasteRejectReasons.Accepted;
string originalText = Text;
string clipboardText = string.Empty;
string textResult = string.Empty;
try
{
clipboardText = Clipboard.GetText(TextDataFormat.Text);
if (clipboardText.Length > 0) // Does clipboard contain text?
{
// Store text value as it will be post paste assuming it is valid.
textResult = (
Text.Remove(SelectionStart,
SelectionLength).Insert(SelectionStart, clipboardText));
foreach (char c in clipboardText) // Check for any non digit characters.
{
if (!char.IsDigit(c))
{
rejectReason = PasteRejectReasons.InvalidCharacter;
break;
}
}
}
else
rejectReason = PasteRejectReasons.NoData;
}
catch
{
rejectReason = PasteRejectReasons.Unknown;
}
return new PasteEventArgs(originalText, clipboardText, textResult, rejectReason);
}
New stuffEvents
Properties
Nested classesThere are two nested event argument classes. KeyRejectedEventArgsAn instance of this is created every time a key down is suppressed. It has just one property:
PasteEventArgsAn instance of this is created every time a Paste message is received. It's used internally, but its primary purpose is as the event args in the
History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||