I have one TextBox with binding on DateTime type. I need to get a dot after first 2 chars and second 2 chars, for example: 12.12.1990.
I'm using behavior in TextChanged event, that code:
void tb_TextChanged(object sender, TextChangedEventArgs e)
{
int i = tb.SelectionStart;
if (i == 2 || i == 5)
{
tb.Text += ".";
tb.SelectionStart = i + 1;
}
}
That is working, but if I want to delete text by backspace, obviously I can't delete dots, because event is called again.
What is better way to solve it?
Solved
It works
But if you can, you may fix my algorithm.
public string oldText = "";
public string currText = "";
private void TextBox1_TextChanged(object sender, TextChangedEventArgs e)
{
oldText = currText;
currText = TextBox1.Text;
if (oldText.Length > currText.Length)
{
oldText = currText;
return;
}
if (TextBox1.Text.Length == currText.Length)
{
if (TextBox1.SelectionStart == 2 || TextBox1.SelectionStart == 5)
{
TextBox1.Text += ".";
TextBox1.SelectionStart = TextBox1.Text.Length;
}
}
}
I would do it in the KeyPress event, so you can filter by what kind of key it was (using the KeyChar argument with Char.IsLetter() and similar functions).
Also, add the dot when the next key is pressed. If the user has typed "12", don't add a dot yet. When the user presses 1 to add the second "12", add it then (before the new character).
Use String Format in the xaml control like so
StringFormat='{}{0:dd.MM.yyyy}'
I just tested it and this will even convert slashes to the dots.
For example
<TextBox.Text>
<Binding Path="Person.DateOfBirth" UpdateSourceTrigger="LostFocus" StringFormat='{}{0:dd.MM.yyyy}'></Binding>
</TextBox.Text>
If you are using a datepicker then you will need to override its textbox template as in the link below with the String Format above.
This link may help if if you are trying to apply it to a datepicker.
I recommend you to use a DateTimePicker and change its Format property to Short. Another option is to change your TextBox to a MaskedTextBox and changing its Mask property to ShortDate (00/00/0000) .DateTimePicker allows you not to do much about validating datetime values. But if you use a MaskedTextBox you should validate it. Sample link shows how to do validation.
I have modified above code
private void txt_in1_TextChanged(object sender, TextChangedEventArgs e)
{
int i = txt_in1.SelectionStart;
if (bsp1 != 1)
{
if (i == 2)
{
txt_in1.Text += ":";
txt_in1.SelectionStart = i + 1;
}
}
}
private void txt_in1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Back)
{
bsp1 = 1;
}
else
{
bsp1 = 0;
}
}
I have taken another event which is keyup (equivalent keypress event), In that whenever backspace is detected it will flag bsp1 variable, which intern stop the text change event to put ":". here "bsp1" is define as global variable. (Code is for wpf, c#).
Related
I have a project in C#.net using a WPF textbox that validates a character like * as the first character entered. If this character is entered, the rest of the text is good but I cannot show nor use the character. How can I remove the character from the string early enough to not show it? I've attempted using the KeyDown event but while the event is active, there is no data to remove. And if I use the KeyUp event the data is shown for a second. I've previously used a KeyPress event in VB6 to achieve this which worked because the value was simultaneously in the code but not in the textbox. As far as I can tell a WPF textbox does not have this event. What can I do?
Code:
private void UserInput_KeyUp(object sender, KeyEventArgs e)
{
//get ascii value from keyboard input
int Ascii = (int)e.Key;
//get char value to know what to remove as a string
char CharAscii = (char)Ascii;
If(Ascii == InputPrefix)
{
PrefixValidated = true;
UserInput.Text = UserInput.Text.Replace(CharAscii.ToString(), string.Empty);
}
}
The same code is in the KeyDown event and I've tried it using one or the other and both.
it may be a bit of a rough solution but you could use a PreviewTextInupt event I belive.
private bool PrefixValidated = false;
private string CheckUserInput;
private void TextBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
CheckUserInput = CheckUserInput + e.Text;
if (CheckUserInput.ElementAt(0).ToString() == "*" && e.Text != "*")
{
e.Handled = false;
}
else if (CheckUserInput.ElementAt(0).ToString() == "*")
{
PrefixValidated = true;
e.Handled = true;
}
else
{
e.Handled = true;
}
}
Thanks to Dark Templar for helping with the discovery of this solution. Using PreviewTextInput and validating the character only if there are no other characters in the textbox seems to give the correct result.
Setting e.Handled = true stops the character from actually entering the textbox even for a second so the user is never aware of the prefix.
Code:
private void UserInput_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
//if this is the first character entered, the textbox is not yet populated
//only perform validation if the character is a prefix
if (UserInput.Text != "")
return;
char CharAscii = (char)ScannerPrefix;
if (e.Text == CharAscii.ToString())
{
PrefixValidated = true;
e.Handled = true;
}
}
This question already has answers here:
How do I make a textbox that only accepts numbers?
(41 answers)
Closed 8 years ago.
I have a textbox with both letters and numbers in and other symbols in which you can find on your keyboard. I have this code which works fine when I manually put the data in and it only lets me put numbers in and deletes letters. Everything what I want, apart from none of it works if the data is copied and pasted in. Below is my code.
private void textBox7_TextChanged(object sender, EventArgs e)
{
Exception X = new Exception();
TextBox T = (TextBox)sender;
T.Text = T.Text.Trim();
try
{
if (T.Text != "-")
{
int x = int.Parse(T.Text);
}
}
catch (Exception)
{
try
{
int CursorIndex = T.SelectionStart - 1;
T.Text = T.Text.Remove(CursorIndex, 1);
//Align Cursor to same index
T.SelectionStart = CursorIndex;
T.SelectionLength = 0;
}
catch (Exception) { }
}
}
The problem with your current code is that you're removing only the last entered character from the cursor position. Pasting text with more than a character breaks your algo.
So let's say you're pasting in 9 letters, the CursorIndex is at 9, you remove only one character (that's the T.Text = T.Text.Remove(CursorIndex, 1); line) and you're left with 8 incorrect ones left.
A better approach (which isn't overly complex like yours) would look like this :
private void textBox7_TextChanged(object sender, EventArgs e)
{
textBox7.Text = string.Concat(textBox7.Text.Where(char.IsDigit));
}
So here we're replacing on each change the text with a new text containing each characters that passes the char.IsDigit test. The cursor won't be at the good position however. Unless multiple edits in the middle of the string are expected, it's probably best to only strap a
textBox1.SelectionStart = textBox1.Text.Length;
at the end of the method, it'll handle pasted text too.
To handle the case where you don't want to erase the character - when it is the only text in your textbox, you can add an obvious if condition. Globally, it'll look like this:
private void textBox7_TextChanged(object sender, EventArgs e)
{
if (textbox7.Text != "-")
textBox7.Text = string.Concat(textBox7.Text.Where(char.IsDigit));
textBox1.SelectionStart = textBox1.Text.Length;
}
Try this. It saves the old value in a var and if the new value cannot be parsed, it reverts the text to old. Otherwise it updates old to the most recent valid value. It's a different approach then you took, but much simpler in my opinion.
string old;
private void textBox7_TextChanged(object sender, EventArgs e) {
int i;
if (textBox1.Text == "" || int.TryParse(textBox7.Text, out i)) {
old = textBox7.Text;
} else {
textBox7.Text = old;
}
}
Basically your problem is that pasting a value will only call the TextChanged event once for the entire change. Your code is relying on the event being called for each character that is put into the textbox.
It sounds like all you really want to do is filter all non numeric values after a possible negative sign. If that is the case you can do it like this.
private void textBox7_TextChanged(object sender, EventArgs e)
{
textBox7.Text = string.Concat(
textBox7.Text.Trim().Where((c,i)=>char.IsDigit(c) || (i==0 && c=='-')));
}
This code is using Linq to go through each character, after trimming leading and trailing white space, and only keeping the ones that are digits or a negative sign if it is the first character. It's equivalent to the following.
private void textBox7_TextChanged(object sender, EventArgs e)
{
StringBuilder builder = new StringBuilder()
string trimmed = textBox7.Text.Trim();
for(int i=0; i<trimmed.Length; i++)
{
char c = trimmed.Text[i];
if(char.IsDigit(c) || (i==0 && c=='-'))
{
builder.Append(c);
}
}
textBox7.Text = builder.ToString();
}
To remove non-numeric characters from the textbox's text, try a regular expression replacement using Regex.Replace
private void numericTextbox_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Text = Regex.Replace(tb.Text, "\\-?[^\d]", "");
}
This will replace any non-numeric character (except a dash at the front, for negative numbers) in your text with nothing every time the text in the box changes, whether the user types something directly or pastes in text from somewhere else.
Alternatively, if you want to keep any dashes (for, say, a phone number):
tb.Text = Regex.Replace(tb.Text, "\\[^-\d]", "");
I'm struggling with copying only letters from clipboard to textbox. I've tried to filter the clipboard and replacing it with only letters with regex, but I want to clipboard stay untouched.
I've tried:
private void Schowek()
{
string schoweczek;
if (Clipboard.ContainsText())
{
schoweczek = Clipboard.GetText();
var schoweczek2 = Regex.Replace(schoweczek, #"[\d-]", string.Empty);
Clipboard.SetText(schoweczek2);
}
}
and
private void textBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Schowek();
}
}
but I think it's not the most efficient way to do that.
UPDATE:
I've come up with sth like this, tho it's not working:
private void textBox1_TextChanged(object sender, EventArgs e)
{
string checkstr=textBox1.Text;
char[] checkchar = checkstr.ToCharArray();
for (int i = 0; i < checkstr.Length; i++)
{
if (Char.IsLetter(checkchar[i])){
}
else
{
checkchar[i] = '\0';
}
}
checkstr=String.Join("", checkchar);
textBox1.Text = textBox1.Text + checkstr;
Instead of trying to hack the native paste function into pasting something other than what is in the clipboard, or changing the contents of the clipboard, you can just subscribe to an event of the textbox and "correct" it's value there.
If you are okay with allowing the user to input anything into the textbox and then cleaning the value once they move to the next control, use the validation events which will only fire after you move to the next field.
If you want instant correction, use the text changed event. But be careful about the amount of code you run in this event as it will fire multiple times rapidly when the user is typing in it. If possible, use the event that only fires after the textbox looses focus.
There is no need to touch the Clipboard at any point for what you are trying to do.
[EDIT]
Also, be wary of disallowing characters in people's names. There are lots of people who have numbers and weird characters in their names.
Falsehoods Programmers Beleive About Names
try this code
string strClip = Clipboard.GetText();
string textvalue = Regex.Replace(strClip, #"\d", "");
first you copy the text from the Clipboard the you replace the digits with "".It work fine i test it.
Take another point of view:
Consider "being" the textbox and watching what is entered or pasted. Then drop anything that is not allowed or (better user experience): allow any input, but deny "OK" and show an error until only valid input is present.
A very common way to achive this for a specific textbox instance is this:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// pseudo-code, fell free to implement it yourself.
if(!IsAllowed(e.KeyChar))
e.Handled = true;
}
private readonly char[] allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
private bool IsAllowed(char c)
{
return allowed.Contains(c);
}
Update
You could use a MaskedTextBox but I think your teacher will consider this cheating ;)
I could think of:
private bool reenter = false;
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (reenter || String.IsNullOrEmpty(textBox1.Text)) return;
var in = textBox1.Text.ToCharArray();
var out = Filter(input).ToArray();
var output = new String(out);
if (!textBox1.Text.Equals(output))
{
reenter = true;
textBox1.Text = output;
reenter = false;
}
}
private IEnumerable<char> Filter(IEnumerable<char> input)
{
foreach(var c in input)
if (IsAllowed(c))
yield return c;
}
Update 2
I just modified your own solution a bit.
First you have to prevent the TextChanged event from fireing multiple times (it fires also if you set the Text from code). You can either set a boolean variable like I did with reenter in my previous example or compare text and new text and only set it's value if different.
Setting a value inside the array to '\0' is wrong because \0 is the string terminator and every char after that is ignored. So if you paste a1b from the clipboard you get a char array { 'a', '\0', 'b' }. NET does not need a string terminator so you would see the result as "a\0b" but if you set the textbox value it will be only a not ab
Anyway, this is my solution. It uses another array and I also memorize SelectionStart to prevent the cursor from jumping to the first position after the text changes.
private void textBox1_TextChanged(object sender, EventArgs e)
{
string checkstr = textBox1.Text;
char[] checkchar = checkstr.ToCharArray();
char[] newchar = new char[checkstr.Length];
int pos = 0;
for (int i = 0; i < checkstr.Length; i++)
{
if (Char.IsLetter(checkchar[i]))
{
newchar[pos] = checkchar[i];
pos++;
}
}
checkstr = String.Join("", newchar);
if (textBox1.Text != checkstr)
{
var start = textBox1.SelectionStart;
textBox1.Text = checkstr;
textBox1.SelectionStart = start;
}
}
I have a problem that is haunting me for a while. I tried some solutions but they didn't worked.
I have a textbox that is for cash input ($999,99 for example). However I need to automatically input the "," and "." to display the value correctly.
I tried two solutions. One of them is this:
private void tx_ValorUnidade_TextChanged(object sender, EventArgs e)
{
string value = tx_ValorUnidade.Text.Replace(",", "").Replace("R$", "");
decimal ul;
//Check we are indeed handling a number
if (decimal.TryParse(value, out ul))
{
//Unsub the event so we don't enter a loop
tx_ValorUnidade.TextChanged -= tx_ValorUnidade_TextChanged;
//Format the text as currency
tx_ValorUnidade.Text = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture("pt-BR"), "{0:C2}", ul);
tx_ValorUnidade.TextChanged += tx_ValorUnidade_TextChanged;
}
}
The result, however, is very weird.
The other one is this:
private void tx_ValorUnidade_KeyUp(object sender, KeyEventArgs e)
{
if (!string.IsNullOrEmpty(tx_ValorUnidade.Text))
{
System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-US");
int valueBefore = Int32.Parse(tx_ValorUnidade.Text, System.Globalization.NumberStyles.AllowThousands);
tx_ValorUnidade.Text = String.Format(culture, "{0:N0}", valueBefore);
tx_ValorUnidade.Select(tx_ValorUnidade.Text.Length, 0); *
}
}
This one kinda works, but there is a issue: if the user wants to insert somethink like $10,00 it can't. It also crashes after 5 numbers.
For original reference, I got the 2 codes from other questions here.
How can I fix it? Am I using the examples wrong? Any thought is welcome.
I think you will be better off when formatting when the user moves to the next control, e.g. like below. Otherwise it will be very confusing as the text will change itself as the user is typing:
private void textBox1_Leave(object sender, EventArgs e)
{
Double value;
if (Double.TryParse(textBox1.Text, out value))
textBox1.Text = String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:C2}", value);
else
textBox1.Text = String.Empty;
}
Some people might want to actually format a textbox as they type. So this is my solution if anyone is looking for one.
It actually assumes you are entering one digit at a time so therefore as you press "1" it assumes "$0.01" and when they press "2" it then assumes "$0.12" and so on and so forth.
I could not find anything online about formatting as they typed. It has been tested and if any errors let me know.
private void textBox1_TextChanged(object sender, EventArgs e)
{
//Remove previous formatting, or the decimal check will fail including leading zeros
string value = textBox1.Text.Replace(",", "")
.Replace("$", "").Replace(".", "").TrimStart('0');
decimal ul;
//Check we are indeed handling a number
if (decimal.TryParse(value, out ul))
{
ul /= 100;
//Unsub the event so we don't enter a loop
textBox1.TextChanged -= textBox1_TextChanged;
//Format the text as currency
textBox1.Text = string.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0:C2}", ul);
textBox1.TextChanged += textBox1_TextChanged;
textBox1.Select(textBox1.Text.Length, 0);
}
bool goodToGo = TextisValid(textBox1.Text);
enterButton.Enabled = goodToGo;
if (!goodToGo)
{
textBox1.Text = "$0.00";
textBox1.Select(textBox1.Text.Length, 0);
}
}
private bool TextisValid(string text)
{
Regex money = new Regex(#"^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$");
return money.IsMatch(text);
}
To make it look nice I'd recommend starting the text box with the text $0.00 on the form load like so:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "$0.00";
textBox1.SelectionStart = inputBox.Text.Length;
}
Just a slight modification to GreatNates answer.
private bool KeyEnteredIsValid(string key)
{
Regex regex;
regex = new Regex("[^0-9]+$"); //regex that matches disallowed text
return regex.IsMatch(key);
}
and insert this method into the textboxs preview input event like this.
private void TextBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = KeyEnteredIsValid(e.Text);
}
That way you make sure that you can't make any mistakes when typing anything. You are limited to numbers only with my methods, while nates methods are formatting your string.
Cheers.
We can try following one as well.
txtCost.Text = String.Format("{0:c2}", myObj.Cost);
I struggled with this for hours too. I tried to use maskedTextBox but that was just clunky for the users to enter text. I also didn't like having to deal with the masking for calculations. I also looked into using the databinding formatting but that just seemed overkill.
The way I ended up going was not to use a TextBox for inputting numbers. Use the NumericUpDown object instead. No need conversion and you can set your decimals and thousands commas in the properties if you like ;) I set my increment to 1000 since i was dealing with income.
Do be aware that the .Text that comes through will have commas when there is a penny decimal and amount over 1000 (i.e. 1,000.01) , otherwise the decimal and trailing 0s are dropped.
I also found this short and sweet solution which worked well but was unneccesary with numericUpDown. You can put this on leave event.
Decimal val;
if (Decimal.TryParse(TxtCosPrice.Text, out val))
TxtCosPrice.Text = val.ToString("C");
else
MessageBox.Show("Oops! Bad input!");
This is my solution, it puts only dots, not money symbol. Hope can help somenone.
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = TextBox2Currency((TextBox)sender, e.KeyValue);
}
private bool TextBox2Currency(TextBox sender,int keyval)
{
if ((keyval >= 48 && keyval <= 58) || keyval == 46 || keyval == 8)
{
int pos = sender.SelectionStart;
int oriLen = sender.Text.Length;
string currTx = sender.Text.Replace(".", "").ToCurrency();
int modLen = currTx.Length;
if (modLen != oriLen)
pos += (modLen - oriLen);
sender.Text = currTx;
if ( pos>=0)
sender.SelectionStart = pos;
return false;
}
return true;
}
I have a textbox that should disallow entering any special characters.
The user can enter :
A-Z
a-z
0-9
Space
How can I make the KeyDown event to do this?
Handling the KeyDown or KeyPress events is one way to do this, but programmers usually forget that a user can still copy-and-paste invalid text into the textbox.
A somewhat better way is to handle the TextChanged event, and strip out any offending characters there. This is a bit more complicated, as you have to keep track of the caret position and re-set it to the appropriate spot after changing the box's Text property.
Depending on your application's needs, I would just let the user type in whatever they want, and then flag the textbox (turn the text red or something) when the user tries to submit.
Just wanted to add some code for those ending up here by search:
private void Filter_TextChanged(object sender, EventArgs e)
{
var textboxSender = (TextBox)sender;
var cursorPosition = textboxSender.SelectionStart;
textboxSender.Text = Regex.Replace(textboxSender.Text, "[^0-9a-zA-Z ]", "");
textboxSender.SelectionStart = cursorPosition;
}
This is a change filter, so handles copy and paste, and preserves cursor position so that changing text in the middle works properly.
Note it uses the 'sender' to get the control name, allowing this one function to be linked to multiple textbox boxes, assuming they need the same filter. You can link multiple controls by going to the event section of a control and manually picking the function for the TextChanged event.
Use a regex to filter out the other characters. Or use Char.IsDigit, IsXXX methods to filter out unwanted characters. Lots of ways to do this.
Update: If you must use KeyDown then it seems that you need to also handle KeyPressed and set obEventArgs.Handled = true to disallow the characters. See the example on the KeyDown MSDN Page
Update: Now that you specify it's WPF. The below code will allow only a-z and A-Z characters to be entered into the textbox. Extend as needed...
private void _txtPath_KeyDown(object sender, KeyEventArgs e)
{
if ((e.Key < Key.A) || (e.Key > Key.Z))
e.Handled = true;
}
This will break if you copy-paste stuff into the text-box. Validate the entire text once the user leaves the control or when he clicks OK/Submit as MusicGenesis says.
private void _txtPath_KeyDown(object sender, KeyEventArgs e)
{
if ((e.Key < Key.A) || (e.Key > Key.Z))
e.Handled = true;
}
I think it's worth considering doing the filtering on the TextBox's TextChanged event. You can create an operation that gets rid of any non-valid characters from your text string. This is a bit more messy than blocking the KeyDown event.
But, I think this is the way to go because you are not blocking WPF's built-in KeyDown/Up event handling mechanisms, so copy/paste still works. You would be working at a higher level of abstractions so I think it will be easier to figure out what is going on.
I ran into this in silverlight and wrote something like this.
private string _filterRegexPattern = "[^a-zA-Z0-9]"; // This would be "[^a-z0-9 ]" for this question.
private int _stringMaxLength = 24;
private void _inputTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (!string.IsNullOrEmpty(_filterRegexPattern))
{
var text = _inputTextBox.Text;
var newText = Regex.Replace(_inputTextBox.Text, _filterRegexPattern, "");
if (newText.Length > _stringMaxLength)
{
newText = newText.Substring(0, _stringMaxLength);
}
if (text.Length != newText.Length)
{
var selectionStart = _inputTextBox.SelectionStart - (text.Length - newText.Length);
_inputTextBox.Text = newText;
_inputTextBox.SelectionStart = selectionStart;
}
}
}
I accomplish this with a custom Dependency Property. It's reusable for any TextBox control, is much faster and more efficient to use than building key events, and makes my code files much cleaner.
In addition, it can handle other input methods which does not trigger key events, such as pasting a value into the TextBox using the mouse.
The code for the custom DP looks like this:
// When set to a Regex, the TextBox will only accept characters that match the RegEx
/// <summary>
/// Lets you enter a RegexPattern of what characters are allowed as input in a TextBox
/// </summary>
public static readonly DependencyProperty AllowedCharactersRegexProperty =
DependencyProperty.RegisterAttached("AllowedCharactersRegex",
typeof(string), typeof(TextBoxProperties),
new UIPropertyMetadata(null, AllowedCharactersRegexChanged));
// Get
public static string GetAllowedCharactersRegex(DependencyObject obj)
{
return (string)obj.GetValue(AllowedCharactersRegexProperty);
}
// Set
public static void SetAllowedCharactersRegex(DependencyObject obj, string value)
{
obj.SetValue(AllowedCharactersRegexProperty, value);
}
// Events
public static void AllowedCharactersRegexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var tb = obj as TextBox;
if (tb != null)
{
if (e.NewValue != null)
{
tb.PreviewTextInput += Textbox_PreviewTextChanged;
DataObject.AddPastingHandler(tb, TextBox_OnPaste);
}
else
{
tb.PreviewTextInput -= Textbox_PreviewTextChanged;
DataObject.RemovePastingHandler(tb, TextBox_OnPaste);
}
}
}
public static void TextBox_OnPaste(object sender, DataObjectPastingEventArgs e)
{
var tb = sender as TextBox;
bool isText = e.SourceDataObject.GetDataPresent(DataFormats.Text, true);
if (!isText) return;
var newText = e.SourceDataObject.GetData(DataFormats.Text) as string;
string re = GetAllowedCharactersRegex(tb);
re = string.Format("[^{0}]", re);
if (Regex.IsMatch(newText.Trim(), re, RegexOptions.IgnoreCase))
{
e.CancelCommand();
}
}
public static void Textbox_PreviewTextChanged(object sender, TextCompositionEventArgs e)
{
var tb = sender as TextBox;
if (tb != null)
{
string re = GetAllowedCharactersRegex(tb);
re = string.Format("[^{0}]", re);
if (Regex.IsMatch(e.Text, re, RegexOptions.IgnoreCase))
{
e.Handled = true;
}
}
}
And it's used like this:
<TextBox Text="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged}"
local:TextBoxHelpers.AllowedCharactersRegex="a-zA-Z0-9\s" />
I know that winForms have available a MaskedTextBox control, which lets you specify exactly this sort of thing. I don't know WPF, so I dunno if that's available there, but if it is, do that. Its MUCH easier than all this stuff with keypresses and events, and more robust too.
The easiest way to do this would be to included the Extended WPF Toolkit which has a control for doing exactly what you are asking for by specifying a mask.
http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox&referringTitle=Home
It will also display the mask in the text box as you are inputting if required.
(It also has many other useful controls)
and your regExp could look like [0-9a-zA-Z]* to allow only English alphanumeric chracters
only alphanumeric TextBox WPF C#,
sorry for my english.. but with this code for WPF, c#, I only permit alphanumeric
private void txtTraslado_TextChanged(object sender, KeyEventArgs e)
{
if (((e.Key < Key.NumPad0)||(e.Key > Key.NumPad9))&&((e.Key < Key.A)||(e.Key > Key.Z)))
{
e.Handled = true;
}
}
Use Asp.NET AJAX Control Toolkit
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
And Use FilteredTextBoxExtender
<asp:TextBox ID="txt_gpf_no" runat="server" CssClass="textbox"
MaxLength="10"></asp:TextBox>
<asp:FilteredTextBoxExtender ID="FilteredTextBoxExtender_gpf_no" runat="server" Enabled="True"
TargetControlID="txt_gpf_no" FilterType="UppercaseLetters,LowercaseLetters,Custom" ValidChars="1234567890 ">
</asp:FilteredTextBoxExtender>
in my.Net Framework 4.5 C# application
private void txtRF_Register_Val_KeyDown(object sender, KeyEventArgs e)
{
//only enable alphanumeric
if (!(((e.KeyCode < Keys.NumPad0) || (e.KeyCode > Keys.NumPad9)) && ((e.KeyCode < Keys.A) || (e.KeyCode > Keys.E))))
{
e.SuppressKeyPress = false;
}
else
{
e.SuppressKeyPress = true;
}
}