TextBox handled doesn't work in some case - c#

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.

Related

How can i capitalize first letter of every word using keypress event with c#?

I must capitalize first letter of every word but with keypress event using C#. Right now every letter in the textbox gets capitalized, I added the code I use. I cant figure out how to capitalize just the first letter, or what am I doing wrong. Can you help me?
private void txt_name_KeyPress(object sender, KeyPressEventArgs e)
{
e.KeyChar = (e.KeyChar.ToString()).ToUpper().ToCharArray()[0];
}
You will need to keep track of previous key presses if you must go this route:
private char PreviousChar;
private void txt_name_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsWhiteSpace(PreviousChar) || PreviousChar == '\0')
{
e.KeyChar = Char.ToUpper(e.KeyChar);
}
PreviousChar = e.KeyChar;
}
I got by using Keydown
private void tbxName_KeyDown(object sender, KeyEventArgs e)
{
if (tbxName.Text.Length == 0 || tbxName.SelectedText.Length == tbxName.Text.Length)
{
if ((e.Key >= Key.A) && (e.Key <= Key.Z))
{
tbxName.Text = e.Key.ToString().ToUpper();
tbxName.SelectionStart = tbxName.Text.Length;
e.Handled = true;
}
}
if (tbxName.Text.Length > 0)
{
int selectionStart = tbxName.SelectionStart;
string character = tbxName.Text.Substring(selectionStart - 1, 1);
if (character.Trim() == string.Empty)
{
if ((e.Key >= Key.A) && (e.Key <= Key.Z))
{
tbxName.Text = tbxName.Text.Insert(selectionStart, e.Key.ToString().ToUpper());
tbxName.SelectionStart = selectionStart + 1;
e.Handled = true;
}
}
}
if (e.Key == Key.Enter || e.Key == Key.Tab)
{
if (tbxName.Text.Length > 2)
{
tbxDegree.Focus();
if (e.Key == Key.Tab)
e.Handled = true;
}
else
{
MessageBox.Show("Kindly verify the Name Entered");
tbxName.Focus();
}
}
}

RichTextBox select all text after Up- / Down-arrow

I have a RichTextBox for which I have created a "scroll through sent messages" feature. This means that if the user sends (by pressing enter) any messages (up to 20), the user can then scroll through them in order by pressing the up/down arrows on the keyboard. This part works as intended.
The issue is: I want to select all text in the RichTextBox after each arrow press.
Here is my code:
private void rtb_inputField_KeyDown(object sender, KeyEventArgs e) {
RichTextBox inputField = (RichTextBox)sender;
string userInput = inputField.Text.Trim();
string[] clientScriptString = userInput.Split(' ');
string modifiedInput = string.Empty;
string macroString = string.Empty;
//Other code...
if (e.KeyData == Keys.Enter) {
//Other code..
if ((client != null) && (client.Connected)) {
macroString = runInputThroughMacroDictionary(userInput);
sendInputToServer(macroString); //Sent message
}
addSentMessageToHistory(userInput); //Added sent message to history
e.Handled = true;
e.SuppressKeyPress = true;
hasUpBeenPressed = false;
}
if ((e.KeyData == Keys.Up) || (e.KeyData == Keys.Down)) {
scrollThroughSentMessages(e);
rtb_inputField.SelectAll();
}
}
private void scrollThroughSentMessages(KeyEventArgs e) {
if (sentMessageHistory.Count > 0) {
if (e.KeyData == Keys.Up) {
if (!hasUpBeenPressed) {
scrollThroughMsgHist = sentMessageHistory.Count - 1;
}
else {
scrollThroughMsgHist--;
if (scrollThroughMsgHist < 0) {
scrollThroughMsgHist = sentMessageHistory.Count - 1;
}
}
hasUpBeenPressed = true;
}
if ((e.KeyData == Keys.Down) && (hasUpBeenPressed)) {
scrollThroughMsgHist++;
if ((scrollThroughMsgHist >= 20) || (scrollThroughMsgHist > (sentMessageHistory.Count - 1))) {
scrollThroughMsgHist = 0;
}
}
rtb_inputField.Text = sentMessageHistory[scrollThroughMsgHist];
}
}
private void addSentMessageToHistory(string message) {
int currentAmountOfMessage = sentMessageHistory.Count;
if (!string.IsNullOrWhiteSpace(message)) {
if (currentAmountOfMessage == 0) {
sentMessageHistory.Add(message);
}
else {
if (sentMessageHistory[currentAmountOfMessage - 1] != message) {
if (currentAmountOfMessage == 20) {
sentMessageHistory.RemoveAt(0);
}
sentMessageHistory.Add(message);
}
}
}
}
The first method does a whole bunch of things. (I removed some of the irrelevant code.) It adds the last sent message to sentMessageHistory (which is a List) via the third method. It also listens for Up/Down, and calls upon the second method.
The second method "scrolls through" each of the entries in the sentMessageHistory -List, and writes it in the RichTextBox. All of this works fine.
What doesn't work is the rtb_inputField.SelectAll(); after the second method has run.
I found the solution. I added the following:
if ((e.KeyData == Keys.Up) || (e.KeyData == Keys.Down)) {
scrollThroughSentMessages(e);
e.Handled = true;
e.SuppressKeyPress = true;
rtb_inputField.SelectAll();
}
I don't know what e.Handled and e.SupressKeyPress does, but it works. So now my code successfully selects the text after "scrolling through history".

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");
}
}
}
}

Two simultaneous Textchanged Events firing in Winforms C#

When I type in the first textbox, it should run a conversion which appears in the second, and when I type in the second, it will appear in the first. However, when I type in the first textchanged event, it triggers the second, which disrupts entering in the first and vice versa. Is there a way I can disable firing the textchanged event when it is highlighted or something?
public void dB10_TextChanged(object sender, EventArgs e)
{
TextBox dB10 = sender as TextBox;
double dBV;
int i = dB10.Text.Trim().Length;
if (i > 0)
{
dBV = Convert.ToDouble(dB10.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
// Controls for if various radiobuttons were clicked
if (dBVRadio.Checked == true)
{
dBV = dBConverter.dBVToVolts(dBV);
voltage.Text = dBV.ToString();
}
else if (dBuRadio.Checked == true)
{
dBV = dBConverter.dBuToVolts(dBV);
voltage.Text = dBV.ToString();
}
}
public void voltage_TextChanged(object sender, EventArgs e)
{
TextBox voltage = sender as TextBox; //V >> dB10 (dBV/dBu)
int i = voltage.Text.Trim().Length;
double volts;
if (i > 0)
{
volts = Convert.ToDouble(voltage.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
if (dBVRadio.Checked == true)
{
dBuRadio.Checked = false;
volts = dBConverter.voltsTodBV(volts);
dB10.Text = volts.ToString();
}
else if (dBuRadio.Checked == true)
{
volts = dBConverter.voltsTodBu(volts);
dB10.Text = volts.ToString();
}
}
you can remove the handler of another textbox and then add it
public void dB10_TextChanged(object sender, EventArgs e)
{
voltage.TextChanged-= voltage_TextChanged;
TextBox dB10 = sender as TextBox;
double dBV;
int i = dB10.Text.Trim().Length;
if (i > 0)
{
dBV = Convert.ToDouble(dB10.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
// Controls for if various radiobuttons were clicked
if (dBVRadio.Checked == true)
{
dBV = dBConverter.dBVToVolts(dBV);
}
else if (dBuRadio.Checked == true)
{
dBV = dBConverter.dBuToVolts(dBV);
}
voltage.Text = dBV.ToString();
voltage.TextChanged+= voltage_TextChanged;
}
You can just use a bool variable:
bool escape = false;
public void dB10_TextChanged(object sender, EventArgs e)
{
if(escape)
return;
escape = true;
// your code
escape = false;
}
public void voltage_TextChanged(object sender, EventArgs e)
{
if(escape)
return;
escape = true;
// your code
escape = false;
}

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