StringFormat、ConverterCulture 和文本框的小数点
StringFormat, ConverterCulture, and a textbox's decimal mark
我想解决我一直以来的一个小怪癖。这并不是一个怪癖,而是一种我想尽可能改变的行为。
如果我使用 {N:2} StringFormat/ConverterCulture,TextBox 将被迫使用小数点 always(即使在输入文本的过程中)。我的意思是,你根本不能删除点或逗号,你必须能够弄清楚你必须移动到数字的下一个 "field" 才能通过单击来编辑小数点将鼠标放在那里或按 "right".
由于这对大多数用户来说是不直观的,有没有一种方法可以避免它而无需重写格式化程序?我希望在现有属性的框架下做一些简单的事情。
例如,XAML TextBox 绑定到 DataGrid 的单元格,
<TextBox Name="TextBox1" Height="18" Margin="0,0,10,0" Text="{Binding SelectedItem[1], ConverterCulture=en-US, ElementName=Grid1, StringFormat={}{0:N2}, UpdateSourceTrigger=PropertyChanged}" Width="59" TextAlignment="Right" VerticalAlignment="Center" />
回答后添加备注:
- UpdateSourceTrigger=PropertyChanged 似乎与此行为直接相关。
- 我怀疑由于既要真正的双向更新又要用户尝试同时干预新输入的逻辑冲突,可能无法实现真正的完整解决方案。
您在 XAML 中设置事件处理程序的方式解释了 TextBox1
控制行为: UpdateSourceTrigger=PropertyChanged
设置默认行为,这意味着源代码控制 (TextBox1
) 在该绑定 属性 更改时更新。您可以考虑其他 TextBox
事件,例如 LostFocus
和 TextChanged
,如下所示 (C#):
TextBox1.LostFocus += (s, e) => TextBox_LostFocus(s, e);
TextBox1.TextChanged += (s, e) => TextBox_TextChanged(s, e);
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
// Your event handling procedure, Formatting, etc.
}
private void TextBox_TextChanged(object sender, RoutedEventArgs e)
{
// Your event handling procedure, Formatting, etc.
}
或使用 Lambda 风格的简化紧凑语法:
TextBox1.LostFocus += (s, e) => {//Your procedure, Formatting, etc};
TextBox1.TextChanged += (s, e) => {//Your procedure, Formatting, etc};
同样可以在 XAML 中声明,但我建议在代码隐藏模块中实现该功能。
关于您的第二个问题,即 CultureInfo
实现:您可以将 CultureInfo
声明保留在 XAML 中,或者在代码隐藏模块中实现它,将其放置在任何上述事件的处理程序,例如(回复:Andrey Gordeev 的 Changing the default thousand and decimal separator in a binding):
String.Format(new CultureInfo("de-DE"), "{0:N}", valueTypeDouble);
希望这可能有所帮助。
我想解决我一直以来的一个小怪癖。这并不是一个怪癖,而是一种我想尽可能改变的行为。
如果我使用 {N:2} StringFormat/ConverterCulture,TextBox 将被迫使用小数点 always(即使在输入文本的过程中)。我的意思是,你根本不能删除点或逗号,你必须能够弄清楚你必须移动到数字的下一个 "field" 才能通过单击来编辑小数点将鼠标放在那里或按 "right".
由于这对大多数用户来说是不直观的,有没有一种方法可以避免它而无需重写格式化程序?我希望在现有属性的框架下做一些简单的事情。
例如,XAML TextBox 绑定到 DataGrid 的单元格,
<TextBox Name="TextBox1" Height="18" Margin="0,0,10,0" Text="{Binding SelectedItem[1], ConverterCulture=en-US, ElementName=Grid1, StringFormat={}{0:N2}, UpdateSourceTrigger=PropertyChanged}" Width="59" TextAlignment="Right" VerticalAlignment="Center" />
回答后添加备注:
- UpdateSourceTrigger=PropertyChanged 似乎与此行为直接相关。
- 我怀疑由于既要真正的双向更新又要用户尝试同时干预新输入的逻辑冲突,可能无法实现真正的完整解决方案。
您在 XAML 中设置事件处理程序的方式解释了 TextBox1
控制行为: UpdateSourceTrigger=PropertyChanged
设置默认行为,这意味着源代码控制 (TextBox1
) 在该绑定 属性 更改时更新。您可以考虑其他 TextBox
事件,例如 LostFocus
和 TextChanged
,如下所示 (C#):
TextBox1.LostFocus += (s, e) => TextBox_LostFocus(s, e);
TextBox1.TextChanged += (s, e) => TextBox_TextChanged(s, e);
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
// Your event handling procedure, Formatting, etc.
}
private void TextBox_TextChanged(object sender, RoutedEventArgs e)
{
// Your event handling procedure, Formatting, etc.
}
或使用 Lambda 风格的简化紧凑语法:
TextBox1.LostFocus += (s, e) => {//Your procedure, Formatting, etc};
TextBox1.TextChanged += (s, e) => {//Your procedure, Formatting, etc};
同样可以在 XAML 中声明,但我建议在代码隐藏模块中实现该功能。
关于您的第二个问题,即 CultureInfo
实现:您可以将 CultureInfo
声明保留在 XAML 中,或者在代码隐藏模块中实现它,将其放置在任何上述事件的处理程序,例如(回复:Andrey Gordeev 的 Changing the default thousand and decimal separator in a binding):
String.Format(new CultureInfo("de-DE"), "{0:N}", valueTypeDouble);
希望这可能有所帮助。