How to enable typing both , and . then formatting it to . for DataGridColumn in all cultures? How to enable typing both , and . then formatting it to . for DataGridColumn in all cultures? wpf wpf

How to enable typing both , and . then formatting it to . for DataGridColumn in all cultures?


You experience the limits when you bind a double (or int) to a TextBox (which is created by the DataGridTextColumn in editing mode): you have only limited influence of foreward and backward conversion from and to a string. One solution to get more control is to introduce a new property which is of type string and represents your double as a string in a format you want. You bind this new property in XAML and do the rest of the magic (foreward, backward conversion) in your viewmodel. Both properties update each other when changed. In other words: the string for the XAML, the double for the model and the viewmodel connects both:

XAML:

<DataGridTextColumn Header="{StaticResource XpStrSize}" Binding="{Binding SizeAsString}" IsReadOnly

Viewmodel:

private double size;public double Size{    get    {        return size;    }    set    {        size = value;        NotifyPropertyChanged ();        sizeAsString = FormatTheDoubleAccordingYourRequirements (size);        NotifyPropertyChanged ("SizeAsString");    }}private string sizeAsString;public string SizeAsString{    get    {        return sizeAsString;    }    set    {        sizeAsString = value;        Size = ParseTheStringAccordingYourRequirements (sizeAsString);        NotifyPropertyChanged ();    }}


This should work with all cultures. Far from perfect but meets minimal requirements.

So my "validation" is only to change incorrect value (like 3.0h or ere) to 1.0

xaml:

<DataGrid.Resources>    <cnv:DoubleToTextConverter x:Key="DoubleToTextConverter" />    <sys:Double x:Key="DoubleOne">1.0</sys:Double></DataGrid.Resources><!-- ... -->    <DataGridTextColumn Header="{StaticResource XpStrSize}" Binding="{Binding Size, Converter={StaticResource DoubleToTextConverter}, ConverterParameter={StaticResource DoubleOne}, UpdateSourceTrigger=LostFocus}" IsReadOnly="False"/>

converter:

public class DoubleToTextConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter,        System.Globalization.CultureInfo culture)    {        return ((double) value).ToString("0.0", System.Globalization.CultureInfo.InvariantCulture);    }    public object ConvertBack(object value, Type targetType, object parameter,        System.Globalization.CultureInfo culture)    {        double doubleValue;        if (double.TryParse(value.ToString().Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture,            out doubleValue))        {            return doubleValue;        }        if (parameter != null && parameter is double)            return (double)parameter;        return 0.0;    }}

property in ViewModel is still double. No additional string property needed.


Please use below code, thats work:

public partial class MainWindow:Window{    public MainWindow()    {        InitializeComponent ();        List<MyClass> myClasses=new List<MyClass> ();        dataGrid.ItemsSource=myClasses;    }}public class MyClass{    public double Size { get; set; }}public class SizeConverter:IValueConverter{    public object Convert(object value,Type targetType,object parameter,System.Globalization.CultureInfo culture)    {        return System.Convert.ToString (value);    }    public object ConvertBack(object value,Type targetType,object parameter,System.Globalization.CultureInfo culture)    {        try        {            string size=System.Convert.ToString (value);            string[] s=size.Split (',');            if (s.Count ()==2)                return System.Convert.ToDouble (s[0]+'.'+s[1]);            else                return System.Convert.ToDouble (value);        }        catch (Exception e)        {            MessageBox.Show (e.Message);        }        return 0;    }}

xaml:

<Window.Resources>    <sc:SizeConverter x:Key="sizeConverter" /></Window.Resources><Grid>    <DataGrid Name="dataGrid" AutoGenerateColumns="False">        <DataGrid.Columns>            <DataGridTextColumn Header="Size" Binding="{Binding Path=Size,Converter={StaticResource sizeConverter}}"  />        </DataGrid.Columns>    </DataGrid></Grid>