Capturing ctrl + multiple key downs - c#

Is there an easy way to capture a ctrl+key1, key2 event in a winforms app similar to that in visual studio such as ctrl+e, c = comment out selected lines?
I am currently overriding my forms OnKeyDown event:
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Control && e.KeyCode.ToString() == "N")
{
//do something...
}
}

The article in the comment may have been for WPF but the idea in it can still be used
Construct a class such as
public class MultiKeyGesture
{
private List<Keys> _keys;
private Keys _modifiers;
public MultiKeyGesture(IEnumerable<Keys> keys, Keys modifiers)
{
_keys = new List<Keys>(keys);
_modifiers = modifiers;
if (_keys.Count == 0)
{
throw new ArgumentException("At least one key must be specified.", "keys");
}
}
private int currentindex;
public bool Matches(KeyEventArgs e)
{
if (e.Modifiers == _modifiers && _keys[currentindex] == e.KeyCode)
//at least a partial match
currentindex++;
else
//No Match
currentindex = 0;
if (currentindex + 1 > _keys.Count)
{
//Matched last key
currentindex = 0;
return true;
}
return false;
}
}
but ignore the inheritance.
to use it
private MultiKeyGesture Shortcut1 = new MultiKeyGesture(new List<Keys> { Keys.A, Keys.B }, Keys.Control);
private MultiKeyGesture Shortcut2 = new MultiKeyGesture(new List<Keys> { Keys.C, Keys.D }, Keys.Control);
private MultiKeyGesture Shortcut3 = new MultiKeyGesture(new List<Keys> { Keys.E, Keys.F }, Keys.Control);
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (Shortcut1.Matches(e))
BackColor = Color.Green;
if (Shortcut2.Matches(e))
BackColor = Color.Blue;
if (Shortcut3.Matches(e))
BackColor = Color.Red;
}

If you only have a two key shortcut, like VS does, you could store the last key pressed in a variable.
private Keys lastKeyPressed = null;
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if(e.Control && lastKeyPressed != null)
{
if(lastKeyPressed == Keys.firstKey && e.KeyCode == Keys.secondKey)
{
}
else if (...) // so on and so forth.
}
else if(e.Control)
lastKeyPressed = e.KeyCode;
}
protected override void OnKeyUp(KeyEventsArgs e)
{
if(!e.Control)
lastKeyPressed = null;
}
This would do a two key shortcut, and would reset it when the ctrl key is released. This is just untested pseudo code but its the concept of saving the last pressed key when Ctrl is being held then resetting it when ctrl is released that I'm trying to convey.

Call e.Modifiers for control key and e.KeyCode for the combined key.
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
// For Tow Key Shortcut.
if (e.Modifiers == Keys.Control && e.KeyCode == Keys.B)
{}
// For Triple Key Shortcut.
if (e.Modifiers.ToString() == (Keys.Shift+", "+Keys.Control) && e.KeyCode == Keys.B)
{}
}
// For Form level Key events you must have to set KeyPreview to True;
public Form1()
{
InitializeComponent();
this.KeyPreview = true;
}

Related

Keydown event how to listen with hotkey

I have registed ctrl+` as a hotkey,and I want to display a window when I press the hotkey and not release the leftctrl key and toggle ` key to do something else just like alt+tab switch the application.Here is the code.
private void ListOnKeyDown(object sender, KeyEventArgs e)
{
if (e.SystemKey==Key.LeftCtrl && e.Key == Key.Oem3)
{
m_host.SelectNext();
}
}
But I found this way only fired one key.So what's the right way to fire the key event?
And here is the debug information.
debug information
Just change your keydown event to detect the modifier this way
private void ListOnKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.Oem3)
{
m_host.SelectNext();
e.Handled = true;
}
}
Because onKeyDown event works for ONE key only, in order to use two keys at same time you need little improvise:
bool firstkeyisOn = false;
private void ListOnKeyDown(object sender, KeyEventArgs e)
{
if (e.SystemKey==Key.LeftCtrl/*Or other key by choice*/)
{
firstkeyisOn = true;
e.Handled = true;
return;
}
if(firstkeyisOn && (e.Key == Key.Oem3/*Or other key by choice*/))
{
m_host.SelectNext();
}
}
private void ListOnKeyUp(object sender, KeyEventArgs e)
{
if (e.SystemKey==Key.LeftCtrl/*Key must be same as holding one*/)
{
firstkeyisOn = false;
}
//or
//firstkeyisOn = false;
}
To cancel hotkey mode you just add firstkeyisOn = false under OnKeyUp event and you good to go.

TextBox handled doesn't work in some case

I have textbox and when i create that form i pass some values and then i prevent user to input some things into textbox based on passed values with this code:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!brojevi && char.IsDigit(e.KeyChar))
{
e.Handled = true;
return;
}
if (!slova && char.IsLetter(e.KeyChar))
{
e.Handled = true;
return;
}
if (!znakovi && char.IsPunctuation(e.KeyChar) || !znakovi && char.IsSymbol(e.KeyChar))
{
e.Handled = true;
return;
}
if (!razmak && char.IsSeparator(e.KeyChar))
{
e.Handled = true;
return;
}
if (maxKaraktera != -1 && (textBox1.Text.Length + 1) > maxKaraktera)
{
e.Handled = true;
return;
}
if (String.IsNullOrWhiteSpace(textBox1.Text))
{
return;
}
if (maxBroj != -1 && Convert.ToDouble(textBox1.Text) > maxBroj)
{
e.Handled = true;
return;
}
}
Problem is that i enabled brojevi and set maxBroj to 10
Now when i try typing some char, it checks and see that slova is not true, set e.Handled = true and return and in my textbox that char is not imputed which is ok.
But when i try inserting number which is greater than 10 (let's say 12), it goes to if statement where it checks if(maxBroj != -1 && Convert.ToDoube(textBox1.Text) > maxBroj) and it enters it, set e.Handled = true and return but number is implemented in textbox.
Why this happens?
EDIT: Code from creating form and form that has textbox
Creating from:
MessageBoxWithValue msg = new MessageBoxWithValue("Unesite kolicinu", "Unesite zeljenu kolicinu. Maksimum: " + aa.maxKolicina.ToString());
msg.brojevi = true;
msg.maxBroj = aa.maxKolicina;
msg.ShowDialog();
if(msg.DialogResult == DialogResult.OK)
{
kol = Convert.ToDouble(msg.returnValue);
}
else
{
return;
}
Here is MessageBoxWithValue form:
public partial class MessageBoxWithValue : Form
{
public bool brojevi = false;
public bool slova = false;
public bool znakovi = false;
public bool razmak = false;
public double maxBroj = -1;
public int maxKaraktera = -1;
public string returnValue;
public MessageBoxWithValue(string naslov, string opis)
{
InitializeComponent();
this.Text = naslov;
label1.Text = opis;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!brojevi && char.IsDigit(e.KeyChar))
{
e.Handled = true;
return;
}
if (!slova && char.IsLetter(e.KeyChar))
{
e.Handled = true;
return;
}
if (!znakovi && char.IsPunctuation(e.KeyChar) || !znakovi && char.IsSymbol(e.KeyChar))
{
e.Handled = true;
return;
}
if (!razmak && char.IsSeparator(e.KeyChar))
{
e.Handled = true;
return;
}
if (maxKaraktera != -1 && (textBox1.Text.Length + 1) > maxKaraktera)
{
e.Handled = true;
return;
}
if (String.IsNullOrWhiteSpace(textBox1.Text))
{
return;
}
if (maxBroj != -1 && Convert.ToDouble(textBox1.Text) > maxBroj)
{
e.Handled = true;
return;
}
}
private void button2_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
{
Uspesno();
}
}
private void button1_Click(object sender, EventArgs e)
{
Uspesno();
}
private void Uspesno()
{
this.DialogResult = DialogResult.OK;
returnValue = textBox1.Text;
}
}
But when i try inserting number which is greater than 10 (let's say 12), it goes to if statement where it checks if(maxBroj != -1 && Convert.ToDoube(textBox1.Text) > maxBroj) and it enters it, set e.Handled = true and return but number is implemented in textbox.
I hope I've got your issue right. You are trying to filter numbers by their values (e.g. maxBroj is set to 10) and you are expecting
if (maxBroj != -1 && Convert.ToDouble(textBox1.Text) > maxBroj)
{
e.Handled = true;
return;
}
not to allow entering a number >10. Unfortunately this will not work as intended, since textBox1.Text won't be set until the KeyPress event handler has finished.
Let's say you are entering 14. When the first KeyPress event is raised (1), textBox1.Text is empty. You are returning from
if (String.IsNullOrWhiteSpace(textBox1.Text))
{
return;
}
Afterwards textBox1.Text is set to "1". Then the second KeyPress event is raised. textBox1.Text is "1", hence the method won't enter the block
if (maxBroj != -1 && Convert.ToDouble(textBox1.Text) > maxBroj)
{
e.Handled = true;
return;
}
Afterwards textBox1.Text will be set to "14", but this is too late for your validation.
You'll have to calculate the expected new value. Please see this question on how to insert the new character in the existing string.

Capture MouseButtons.XButton1/2 for Forward/Backward navigation Windows 10

I want to capture the MouseButtons.XButton 1 and 2 and enable backward and forward navigation.
In Windows 10 I can capture mouse clicks using
this.PointerPressed += LevelsPage_PointerPressed;
private void LevelsPage_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
{
}
}
But how do I determine the pointer is MouseButtons.XButton or rather PointerRoutedEventArgs is of type MouseEventArgs? Once determined, I plan to handle the navigation using something like
if (pointer == MouseButton.XButton2 && this.Frame.CanGoBack)
{
this.Frame.GoBack();
e.Handled = true;
}
else if (pointer == MouseButton.XButton1 && this.Frame.CanGoForward)
{
this.Frame.GoForward();
e.Handled = true;
}
I figured it out. Here's how I do it
private void LevelsPage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
PointerPoint currentPoint = e.GetCurrentPoint(this);
if (currentPoint.PointerDevice.PointerDeviceType == PointerDeviceType.Mouse)
{
PointerPointProperties pointerProperties = currentPoint.Properties;
if (pointerProperties.IsXButton1Pressed && this.Frame.CanGoBack)
{
this.Frame.GoBack();
}
else if (pointerProperties.IsXButton2Pressed && this.Frame.CanGoForward)
{
this.Frame.GoForward();
}
}
}

allow textbox to support numbers and OemMinus only?

In my code I use this piece of code to validate textbox to support only, but I want to allow OemMinus (-) also how can I do this?
private void card_No_KeyDown(object sender, KeyEventArgs e)
{
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9 &&
e.KeyCode == Keys.Oemplus)
{
// Determine whether the keystroke is a backspace.
if (e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
}
private void card_No_KeyPress(object sender, KeyPressEventArgs e)
{
if (nonNumberEntered == true)
{
MessageBox.Show("not allowed");
e.Handled = true;
}
}
You could handle the KeyPress event like this
private void card_No_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsNumber(e.KeyChar) && e.KeyChar != '-' && e.KeyChar != (char)Keys.Back)
e.Handled = true;
}
But that won't prevent the user from copy pasting an invalid value so you can also handle the TextChanged event.
private void card_No_TextChanged(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(card_No.Text))
{
if (Regex.Matches(card_No.Text, #"(-|\d)").Count != card_No.Text.Length)
{
//pasted an invalid value
MessageBox.Show("Invalid value entered");
}
}
}
private void card_No_KeyPress(object sender, KeyPressEventArgs e)
{
var textBox = sender as TextBox;
//handels integers, decimal numbers and OemMinus (-) character
if (((!char.IsControl(e.KeyChar))
&& (!char.IsDigit(e.KeyChar))
&& (e.KeyChar != '-')
) || (textBox != null
&& (e.KeyChar != '.'
&& (textBox.Text.IndexOf('.') > -1))))
e.Handled = true;
if (e.Handled)
MessageBox.Show(#"not allowed");
}
//prevent copy and past and delete pasted text
private void card_No_TextChanged(object sender, EventArgs e)
{
if (card_No.Text.Length >0)
{
if (Regex.Matches(card_No.Text, #"(-|\d)").Count != card_No.Text.Length)
{
if (!Clipboard.ContainsText()) return;
var txt = Clipboard.GetText();
if (card_No.Text.Contains(txt))
{
int ind = card_No.Text.IndexOf(txt, System.StringComparison.Ordinal);
var text = card_No.Text.Substring(0, ind);
card_No.Text = text;
MessageBox.Show(#"not allowed");
}
else if (txt.Contains(card_No.Text))
{
int ind = txt.IndexOf(card_No.Text, System.StringComparison.Ordinal);
var text = txt.Substring(0, ind);
card_No.Text = text;
MessageBox.Show(#"not allowed");
}
}
}
}

Best way to limit textbox decimal input in c#

How can I make a textbox in which can be only typed a number like 12.00 or 1231231.00 or 123123
I've done this in a very long way and I'm looking for the best and fastest way.
Also the decimal separator must be culture specific.:
Application.CurrentCulture.NumberFormat.NumberDecimalSeparator
The Validating event was made to do that. Drop an ErrorProvider control on your form so you can subtly remind the user that she did something wrong. The event also allows you to format the text box text the way that make sense. Like this:
private void textBox1_Validating(object sender, CancelEventArgs e) {
// Empty strings okay? Up to you.
if (textBox1.Text.Length > 0) {
decimal value;
if (decimal.TryParse(textBox1.Text, out value)) {
textBox1.Text = value.ToString("N2");
errorProvider1.SetError(textBox1, "");
}
else {
e.Cancel = true;
textBox1.SelectAll();
errorProvider1.SetError(textBox1, "Please enter a number");
}
}
}
That's a fairly straightforward operation. You'll need to filter the keys that you don't want out and then perform some additional checks.
Add the following code to the KeyDown event of the textbox:
private void TextBox1_KeyDown(object sender,
System.Windows.Forms.KeyEventArgs e)
{
switch (e.KeyCode) {
case Keys.D0:
case Keys.D1:
case Keys.D2:
case Keys.D3:
case Keys.D4:
case Keys.D5:
case Keys.D6:
case Keys.D7:
case Keys.D8:
case Keys.D9:
case Keys.NumPad0:
case Keys.NumPad1:
case Keys.NumPad2:
case Keys.NumPad3:
case Keys.NumPad4:
case Keys.NumPad5:
case Keys.NumPad6:
case Keys.NumPad7:
case Keys.NumPad8:
case Keys.NumPad9:
//allow numbers only when no modifiers are active
if (e.Control || e.Alt || e.Shift) {
//suppress numbers with modifiers
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
}
break;
case (Keys)110:
case Keys.OemPeriod:
if (!((TextBox)sender).Text.Contains(".")) {
//allow period key if there is no '.'
//in the text and no modifiers are active
if (e.Control || e.Alt || e.Shift) {
//suppress numbers with modifiers
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
}
} else {
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
}
break;
case Keys.Subtract:
case Keys.OemMinus:
if (((TextBox)sender).SelectionStart == 0 &&
!((TextBox)sender).Text.Contains("-")) {
//allow the negative key only when the cursor
//is at the start of the textbox
//and there are no minuses in the textbox
//and no modifiers are active
if (e.Control || e.Alt || e.Shift) {
//suppress numbers with modifiers
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
}
} else {
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
}
break;
case Keys.C:
case Keys.X:
case Keys.V:
case Keys.Z:
//allow copy, cut, paste & undo by checking for
//the CTRL state.
if (e.Control == false) {
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
}
break;
case Keys.Control:
case Keys.ControlKey:
case Keys.Alt:
case Keys.Shift:
case Keys.ShiftKey:
//allow control, alt & shift
break;
case Keys.Left:
case Keys.Right:
case Keys.Up:
case Keys.Down:
case Keys.PageUp:
case Keys.PageDown:
case Keys.Home:
case Keys.End:
//allow navigation keys
break;
case Keys.Back:
case Keys.Delete:
//allow backspace & delete
break;
default:
//suppress any other key
e.SuppressKeyPress = true;
e.Handled = true;
Interaction.Beep();
break;
}
}
And then, since a user may paste values into the textbox, you add the following to the TextBox's Validate event
private void TextBox1_Validating(object sender,
System.ComponentModel.CancelEventArgs e)
{
//just in case a value was pasted,
//we'll need to validate the value
if (!Information.IsNumeric(((TextBox)sender).Text))
{
e.Cancel = true;
}
}
I wrote a class to handle a variety of filters for you [which obviously includes the culture-specific decimal symbol].
Add this class to your project
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class TextBoxFilter
{
[Flags()]
public enum Filters
{
None = 0,
Text = 1,
Numbers = 2,
AlphaNumeric = Filters.Text | Filters.Numbers,
Currency = 4,
All = Filters.Text | Filters.Numbers | Filters.Currency
}
Dictionary<TextBox, Filters> _keyFilter;
Dictionary<TextBox, string> _allowedKeys;
Dictionary<TextBox, string> _invalidKeys;
Dictionary<TextBox, Windows.Forms.KeyEventArgs> keyEventArgs;
private static string DecimalMark = Application.CurrentCulture.NumberFormat.NumberDecimalSeparator;
private static string NegativeMark = Application.CurrentCulture.NumberFormat.NegativeSign;
private static string CurrencySymb = Application.CurrentCulture.NumberFormat.CurrencySymbol;
private static string CurrencyDecimal = Application.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
public TextBoxFilter()
{
_keyFilter = new Dictionary<TextBox, Filters>();
_allowedKeys = new Dictionary<TextBox, string>();
_invalidKeys = new Dictionary<TextBox, string>();
keyEventArgs = new Dictionary<TextBox, KeyEventArgs>();
}
//set & remove filter
public void SetTextBoxFilter(TextBox textBox, Filters filter)
{
SetTextBoxFilter(textBox, filter, AllowedKeys(textBox), InvalidKeys(textBox));
}
public void SetTextBoxFilter(TextBox textBox, string allowedKeys)
{
SetTextBoxFilter(textBox, Strings.Filter(textBox), allowedKeys, InvalidKeys(textBox));
}
public void SetTextBoxFilter(TextBox textBox, string allowedKeys, string invalidKeys)
{
SetTextBoxFilter(textBox, Strings.Filter(textBox), allowedKeys, invalidKeys);
}
public void SetTextBoxFilter(TextBox textBox, Filters filter, string allowedKeys, string invalidKeys)
{
if (!_keyFilter.ContainsKey(textBox)) {
//add the textbox and its filter if it does not exist in
//the collection of registered textboxes
_keyFilter.Add(textBox, filter);
_allowedKeys.Add(textBox, allowedKeys);
_invalidKeys.Add(textBox, invalidKeys);
keyEventArgs.Add(textBox, new System.Windows.Forms.KeyEventArgs(Keys.None));
//add the event handlers
textBox.KeyDown += KeyDownUp;
textBox.KeyUp += KeyDownUp;
textBox.KeyPress += KeyPress;
textBox.Validating += Validating;
textBox.Disposed += Disposed;
} else {
//change the filter of the textbox if it exists in
//the collection of registered textboxes
_keyFilter(textBox) = filter;
_allowedKeys(textBox) = allowedKeys;
_invalidKeys(textBox) = invalidKeys;
}
}
public void RemoveTextBoxFilter(TextBox textBox)
{
if (_keyFilter.ContainsKey(textBox)) {
_keyFilter.Remove(textBox);
_allowedKeys.Remove(textBox);
_invalidKeys.Remove(textBox);
keyEventArgs.Remove(textBox);
textBox.KeyDown -= KeyDownUp;
textBox.KeyUp -= KeyDownUp;
textBox.KeyPress -= KeyPress;
textBox.Validating -= Validating;
textBox.Disposed -= Disposed;
}
}
public bool ContainsTextBox(TextBox textBox)
{
return _keyFilter.ContainsKey(textBox);
}
//properties
public Filters Filter {
get {
if (ContainsTextBox(textBox)) {
return _keyFilter.Item[textBox];
} else {
return Filters.None;
}
}
set { SetTextBoxFilter(textBox, value); }
}
public string AllowedKeys {
get {
if (ContainsTextBox(textBox)) {
return _allowedKeys(textBox);
} else {
return "";
}
}
set { SetTextBoxFilter(textBox, this.Filter(textBox), value, this.InvalidKeys(textBox)); }
}
public string InvalidKeys {
get {
if (ContainsTextBox(textBox)) {
return _invalidKeys(textBox);
} else {
return "";
}
}
set { SetTextBoxFilter(textBox, this.Filter(textBox), this.AllowedKeys(textBox), value); }
}
//event handlers
private void Disposed(object sender, System.EventArgs e)
{
RemoveTextBoxFilter((TextBox)sender);
}
private void KeyDownUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
//assign the modifiers
keyEventArgs((TextBox)sender) = e;
}
private void KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
//ensure key pressed is in the allowed keys
object txt = (TextBox)sender;
object c = e.KeyChar;
bool allowKey = IsValidChar(txt, c, txt.SelectionStart);
//check for backspace & Ctrl combinations if the allowKey is still false
if (allowKey == false) {
if (keyEventArgs(txt).Control) {
//control modifier goes with A, X, C, V and Z for
//Select All, Cut, Copy, Paste and Undo respectively
object key = keyEventArgs(txt).KeyCode;
allowKey = (key == Keys.A || key == Keys.X || key == Keys.C || key == Keys.V || key == Keys.Z);
} else if (keyEventArgs(txt).KeyCode == Keys.Back) {
//allow the backspace key
allowKey = true;
}
}
//disable the key if it was not valid
if (!allowKey) {
e.Handled = true;
Interaction.Beep();
}
}
private void Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
object box = (TextBox)sender;
object boxFlags = _keyFilter(box);
//skip validation if the textbox allows all entries or there is no text
if (boxFlags == Filters.All | string.IsNullOrEmpty(box.Text))
return;
//otherwise check the characters entered
object txtChars = box.Text.ToCharArray;
bool isValidEntry = false;
//check each caracter for an invalid entry
for (i = 0; i <= txtChars.Length - 1; i++) {
object c = txtChars(i);
isValidEntry = IsValidChar(box, txtChars(i), i);
if (!isValidEntry) {
box.Select(i, 1);
break; // TODO: might not be correct. Was : Exit For
}
}
if (!isValidEntry)
e.Cancel = true;
if (!isValidEntry) {
Interaction.MsgBox("The text entered is invalid for the format " + boxFlags.ToString + "." + !string.IsNullOrEmpty(_allowedKeys(box)) ? Constants.vbCrLf + "Additional Allowed Keys: " + _allowedKeys(box) : "" + !string.IsNullOrEmpty(_invalidKeys(box)) ? Constants.vbCrLf + "Additional Invalid Keys: " + _invalidKeys(box) : "", MsgBoxStyle.Critical, "Invalid Entry");
}
}
private bool IsValidChar(TextBox textBox, char c, int charIndex)
{
//ensure key pressed is in the allowed keys
object pF = _keyFilter(textBox);
object aK = _allowedKeys(textBox);
object iK = _invalidKeys(textBox);
bool shouldAllow = false;
//if filter is set to all, return true unconditionally
if (pF == Filters.All)
return true;
//check preset filters
//check for text
if (EnumHasFlag(pF, Filters.Text)) {
if (!char.IsDigit(c)) {
shouldAllow = true;
} else {
//if the character is a digit, check for the number flag (AlphaNumerics)
if (EnumHasFlag(pF, Filters.Numbers)) {
shouldAllow = true;
}
}
}
//check for nubers
if (shouldAllow == false && EnumHasFlag(pF, Filters.Numbers)) {
if (char.IsDigit(c)) {
shouldAllow = true;
} else if (DecimalMark.Contains(c)) {
//allow the decimal if there is no decimal in the textbox's
//text or the selected text contains the mark
if (!textBox.Text.Substring(0, charIndex).Contains(c) || textBox.SelectedText.Contains(c)) {
shouldAllow = true;
}
} else if (NegativeMark.Contains(c) && (charIndex <= NegativeMark.IndexOf(c))) {
//allow the negative mark if we are at the start of the
//textbox
shouldAllow = true;
}
}
//check for currency
if (shouldAllow == false && EnumHasFlag(pF, Filters.Currency)) {
if (char.IsDigit(c)) {
shouldAllow = true;
} else if (CurrencyDecimal.Contains(c)) {
//allow the currency decimal mark if it does not exist in the
//textbox's text or the selected text contains the mark
if (!textBox.Text.Substring(0, charIndex).Contains(c) || textBox.SelectedText.Contains(c)) {
shouldAllow = true;
}
} else if (CurrencySymb.Contains(c) && (charIndex <= CurrencySymb.IndexOf(c))) {
//allow the currency symbol if we are in a valid position
shouldAllow = true;
}
}
//now check for extra allowed keys
if (!shouldAllow) {
shouldAllow = aK.Contains(c);
}
//and then check for extra invalid keys
if (shouldAllow && iK.Contains(c)) {
shouldAllow = false;
}
return shouldAllow;
}
[System.Diagnostics.DebuggerStepThrough()]
private bool EnumHasFlag(Enum value, Enum flag)
{
return (Convert.ToInt64(value) & Convert.ToInt64(flag)) == Convert.ToInt64(flag);
}
}
and then use it in your form as follows
public class Form1
{
TextBoxFilter filter = new TextBoxFilter();
private void Form1_Load(object sender, System.EventArgs e)
{
filter.SetTextBoxFilter(TextBox1, TextBoxFilter.Filters.Numbers);
}
public Form1()
{
Load += Form1_Load;
}
}
Try the MaskedTextBox control.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsNumber(e.KeyChar))
{
e.Handled = !(((TextBox)sender).SelectionStart != 0 && (e.KeyChar.ToString() == Application.CurrentCulture.NumberFormat.NumberDecimalSeparator && ((TextBox)sender).Text.IndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) == -1));
}
}
And you should check onLeave for Length == 0 I think...

Categories