Hi peeps,
You probably know the common issue with the decimal seprator. Depending on the country, the keyboard or what your client wants (which can be variable…), the separator will be a coma or a dot (or even something else…).
In my case, the Culture is “en-US“, on a Belgian keyboard where the decimal separator should be a coma. No worries, these parameters can be changed easily.
First of all, set the CultureInfo globally for your application (in the code behind of your MainView or in my case in the MainVM.cs).
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); var currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name; var ci = new CultureInfo(currentCulture) { NumberFormat = { NumberDecimalSeparator = "," }, DateTimeFormat = { DateSeparator = "/" } }; System.Threading.Thread.CurrentThread.CurrentCulture = ci; System.Threading.Thread.CurrentThread.CurrentUICulture = ci; FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
Adapt the NumberDecimalSeparator and/or the DateSeparator here as well.
In the View, you can now adapt the TextBox to have something like:
<TextBox Text="{Binding Value, StringFormat={}{0:0.00}, Mode=TwoWay}" PreviewTextInput="OnPreviewTextInput"/>
PreviewTextInput is an event that will be raised when you enter a new character inside the TextBox.
Now in the code behind of your View, just add this method:
private void OnPreviewTextInput(object sender, TextCompositionEventArgs e) { //This method is a hack to be able to replace a dot by a coma without using the KeyPressed event /* * Valid values: * 1,2 --> 1,2 * -1,2 --> -1,2 * ,2 --> 0,2 * -,2 --> -0,2 */ var textBox = ((TextBox) sender); //Get the txtBox control var newChar = e.Text; //Get the new inserted character if (newChar == "\r") //Simulate a TAB if user pressed Enter { var request = new TraversalRequest(FocusNavigationDirection.Next); request.Wrapped = true; ((TextBox)sender).MoveFocus(request); } if (newChar.Contains(".")) //Replace the new character by a coma if it's a dot newChar = newChar.Replace('.', ','); if (textBox.SelectionLength > 0) //Clear the content of the txtBox if there is a selection textBox.Text = string.Empty; var input = textBox.Text + newChar; //Get the full string including the new character to validate via a regex var pattern = string.Format("^[-]?([0-9]?)+[{0}]?([0-9]+)?$", //http://www.regexr.com/ Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator); var regex = new Regex(pattern); var isValid = !regex.IsMatch(input); if (textBox.Text.Contains(".")) //Replace the coma by a dot in the existing string textBox.Text = textBox.Text.Replace('.', ',') + e.Text; if (textBox.SelectionLength == 0) //If there is no selection, put the cursor at the end of the string textBox.CaretIndex = textBox.Text.Length; e.Handled = isValid; //If the pattern is valid then the new character can be added }
Adapt if needed of course…
Happy coding! 🙂