如何使用样式/模板格式化 wpf 中的小数位数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18361689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to format number of decimal places in wpf using style/template?
提问by AXG1010
I am writing a WPF program and I am trying to figure out a way to format data in a TextBox through some repeatable method like a style or template. I have a lot of TextBoxes (95 to be exact) and each one is bound to its own numeric data which can each have their own resolution defined. For example if the data is 99.123 with a resolution of 2 then it should display 99.12. Similarly a data value of 99 and resolution 3 should be displayed as 99.000 (not 99). Is there a way to do this?
我正在编写一个 WPF 程序,我试图找出一种方法,通过一些可重复的方法(如样式或模板)来格式化 TextBox 中的数据。我有很多文本框(准确地说是 95 个),每个文本框都绑定到自己的数字数据,每个数据都可以定义自己的分辨率。例如,如果数据是 99.123,分辨率为 2,那么它应该显示 99.12。同样,数据值 99 和分辨率 3 应显示为 99.000(而不是 99)。有没有办法做到这一点?
Edit:I should clarify, there are 95 TextBoxes on the current screen I'm working on, but I want every TextBox throughout the various screens in my program to display the correct number of decimal places. Now that I think about it, some of these are TextBoxes (like the screen I'm working on now) and some are DataGrids or ListViews, but if I can figure out how to get it working for TextBoxes I'm sure I can figure it out for the other controls as well.
编辑:我应该澄清一下,我正在处理的当前屏幕上有 95 个文本框,但我希望程序中各个屏幕中的每个文本框都显示正确的小数位数。现在我考虑了一下,其中一些是 TextBoxes(就像我现在正在处理的屏幕一样),一些是 DataGrids 或 ListViews,但是如果我能弄清楚如何让它为 TextBoxes 工作,我相信我可以弄清楚它也用于其他控件。
There's not much code to share in this case but I'll attempt to make it clearer:
在这种情况下没有太多代码可以共享,但我会尝试使其更清晰:
I have a View Model which contains the following properties (vb.net):
我有一个包含以下属性的视图模型(vb.net):
Public ReadOnly Property Resolution As Integer
Get
Return _signal.DisplayResolution
End Get
End Property
Public ReadOnly Property Value As Single
Get
Return Math.Round(_signal.DisplayValue, Resolution)
End Get
End Property
and in the XAML I have:
在 XAML 中,我有:
<UserControl.Resources>
<vm:SignalViewModel x:Key="Signal" SignalPath="SomeSignal"/>
</UserControl.Resources>
<TextBox Grid.Column="3" IsEnabled="False" Text="{Binding Path=Value, Source={StaticResource Signal}, Mode=OneWay}" />
EDIT2 (my solution):It turns out that after walking away from the computer for a while, I came back to find a simple answer that was staring me in the face. Format the data in the view model!
EDIT2(我的解决方案):事实证明,在离开计算机一段时间后,我回来寻找一个简单的答案,它正盯着我的脸。格式化视图模型中的数据!
Public ReadOnly Property Value As String
Get
Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
End Get
End Property
回答by Abe Heidebrecht
You should use the StringFormat
on the Binding
. You can use either standard string formats, or custom string formats:
您应该StringFormat
在Binding
. 您可以使用标准字符串格式或自定义字符串格式:
<TextBox Text="{Binding Value, StringFormat=N2}" />
<TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />
Note that the StringFormat
only works when the target property is of type string. If you are trying to set something like a Content
property (typeof(object)
), you will need to use a custom StringFormatConverter
(like here), and pass your format string as the ConverterParameter
.
请注意,StringFormat
只有当目标属性是字符串类型时才有效。如果您尝试设置诸如Content
属性 ( typeof(object)
) 之类的内容,则需要使用自定义项StringFormatConverter
(如此处),并将格式字符串作为ConverterParameter
.
Edit for updated question
编辑更新的问题
So, if your ViewModel
defines the precision, I'd recommend doing this as a MultiBinding
, and creating your own IMultiValueConverter
. This is pretty annoying in practice, to go from a simple binding to one that needs to be expanded out to a MultiBinding
, but if the precision isn't known at compile time, this is pretty much all you can do. Your IMultiValueConverter
would need to take the value, and the precision, and output the formatted string. You'd be able to do this using String.Format
.
所以,如果你ViewModel
定义的精确度,我建议这样做的MultiBinding
,和创建自己的IMultiValueConverter
。这在实践中很烦人,从一个简单的绑定到一个需要扩展到 a 的绑定MultiBinding
,但如果在编译时不知道精度,这几乎是你所能做的。您IMultiValueConverter
需要获取值和精度,并输出格式化的字符串。您可以使用String.Format
.
However, for things like a ContentControl
, you can much more easily do this with a Style
:
但是,对于 a 之类的东西ContentControl
,您可以使用 a 更轻松地做到这一点Style
:
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentStringFormat"
Value="{Binding Resolution, StringFormat=N{0}}" />
</Style>
Any control that exposes a ContentStringFormat
can be used like this. Unfortunately, TextBox
doesn't have anything like that.
任何暴露 a 的控件ContentStringFormat
都可以这样使用。不幸的是,TextBox
没有这样的东西。
回答by Manish Dubey
The accepted answer does not show 0 in integer place on giving input like 0.299. It shows .3 in WPF UI. So my suggestion to use following string format
接受的答案在给出像 0.299 这样的输入时没有在整数位置显示 0。它在 WPF UI 中显示 .3。所以我建议使用以下字符串格式
<TextBox Text="{Binding Value, StringFormat={}{0:#,0.0}}"
回答by Monali Pawar
void NumericTextBoxInput(object sender, TextCompositionEventArgs e)
{
TextBox txt = (TextBox)sender;
var regex = new Regex(@"^[0-9]*(?:\.[0-9]{0,1})?$");
string str = txt.Text + e.Text.ToString();
int cntPrc = 0;
if (str.Contains('.'))
{
string[] tokens = str.Split('.');
if (tokens.Count() > 0)
{
string result = tokens[1];
char[] prc = result.ToCharArray();
cntPrc = prc.Count();
}
}
if (regex.IsMatch(e.Text) && !(e.Text == "." && ((TextBox)sender).Text.Contains(e.Text)) && (cntPrc < 3))
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}