如何同时输入 , 和 .然后将其格式化为 .用于所有文化中的 DataGridColumn?
Posted
技术标签:
【中文标题】如何同时输入 , 和 .然后将其格式化为 .用于所有文化中的 DataGridColumn?【英文标题】:How to enable typing both , and . then formatting it to . for DataGridColumn in all cultures? 【发布时间】:2017-05-18 00:44:11 【问题描述】:无论文化如何,我都需要在可编辑的 DataGridColumn 中同时接受 ,
和 .
。输入值时,它的格式设置为使用.
作为小数分隔符。
目前我只使用:
<DataGridTextColumn Header="StaticResource XpStrSize" Binding="Binding Size" IsReadOnly="False"/>
ViewModel 中绑定的属性 Size 是 double 类型。
所以如果用户输入 100,3 它应该在绑定属性中更新为 100.3。他也可以输入2.0,应该是2.0。此外,当用户输入 100,3 时,当焦点离开该字段时,它在列中更新为 100.3。
【问题讨论】:
您是否也接受','
作为数字分隔符?
没有。仅适用于十进制。好点子。在我的文化中,那些不被使用
那就用string formatted = raw.Replace(',', '.');
在哪里?我使用 MVVM,绑定属性是 double 类型。我想用 XAML 或比将绑定属性的类型更改为字符串更优雅的方式来解决这个问题。
我不确定仅在 XAML 中是否有办法做到这一点,所以如果有比我更了解该主题的人出现,也许他们可以说。否则,您可能需要编写一个自定义的BindingConverter
来进行转换。
【参考方案1】:
当您将 double(或 int)绑定到 TextBox
(由 DataGridTextColumn
在编辑模式下创建)时,您会遇到限制:您对字符串的前向和后向转换的影响有限.获得更多控制权的一种解决方案是引入一个字符串类型的新属性,并将您的 double 表示为您想要的格式的字符串。您在 XAML 中绑定这个新属性并在视图模型中执行其余的魔法(前向、后向转换)。两个属性在更改时会相互更新。换句话说:XAML 的字符串、模型的双精度和视图模型连接两者:
XAML:
<DataGridTextColumn Header="StaticResource XpStrSize" Binding="Binding SizeAsString" IsReadOnly
视图模型:
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 ();
【讨论】:
这不允许在列的文本框中写入任何内容吗? 我不确定你的问题是什么意思。使用这种方法,DataGridTextColumn
“看到”了一个只能被编辑的字符串。但是你的主人是一个替身,你来回转换它。字符串为您提供所需的所有灵活性。顺便说一句,在编辑期间进行复杂的数据验证时,这样做是某种标准。
我的意思是,如果我只是绑定到双精度,我会在文本框周围出现红色边框,如果它不是合法的双精度。这不也是一个无限循环吗?无限期地从一个集合到另一个集合?
我很抱歉你是绝对正确的,这是一个无限循环。我修改了我的答案。但通常我试图展示的想法需要适应每个具体情况。是的,绑定到字符串时会丢失数据验证。不幸的是,你正处于一个全取或全取的情况。
谢谢!是的,通过简单的解决方案,我失去了数据验证。但是,这是可以肯定的。我目前正在尝试使用 double 属性和 Converter 来实现这个东西,绑定中会引发异常,我正在检查是否为该列设置 ValidatesOnExceptions=True 是否值得研究。【参考方案2】:
这应该适用于所有文化。远非完美,但满足最低要求。
所以我的“验证”只是将不正确的值(如 3.0h 或 ere)更改为 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"/>
转换器:
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;
ViewModel 中的属性仍然是双倍的。不需要额外的字符串属性。
【讨论】:
为什么要投反对票?诚实的问题。我不知道这有什么问题。【参考方案3】:请使用下面的代码,就可以了:
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>
【讨论】:
以上是关于如何同时输入 , 和 .然后将其格式化为 .用于所有文化中的 DataGridColumn?的主要内容,如果未能解决你的问题,请参考以下文章
如何从数据框中提取值以用于条件格式,同时一次将其应用于某些选择类别或数据条目?