如何使用样式/模板格式化wpf中的小数位数?

时间:2013-08-21 15:33:11

标签: wpf xaml data-binding string-formatting

我正在编写一个WPF程序,我试图通过一些可重复的方法(如样式或模板)找到一种在TextBox中格式化数据的方法。我有很多TextBoxes(确切地说是95),每一个都绑定到自己的数值数据,每个数据都可以定义自己的分辨率。例如,如果数据为99.123,分辨率为2,则应显示99.12。同样,数据值99和分辨率3应显示为99.000(而不是99)。有没有办法做到这一点?

修改 我应该澄清一下,我正在处理的当前屏幕上有95个TextBox,但是我希望程序中各个屏幕上的每个TextBox都显示正确的小数位数。现在我考虑一下,其中一些是TextBoxes(就像我现在正在处理的屏幕),有些是DataGrids或ListViews,但如果我能弄清楚如何让它适用于TextBoxes我敢肯定我能想到它也用于其他控件。

在这种情况下分享的代码不多,但我会尝试更清楚地说明:

我有一个View Model,它包含以下属性(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

在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(我的解决方案): 事实证明,在离开电脑一段时间之后,我回来找到一个简单的答案,盯着我的脸。在视图模型中格式化数据!

    Public ReadOnly Property Value As String
        Get
            Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
        End Get
    End Property

3 个答案:

答案 0 :(得分:160)

您应该使用StringFormat上的Binding。您可以使用standard string formatscustom string formats

<TextBox Text="{Binding Value, StringFormat=N2}" />
<TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />

请注意,StringFormat仅在target属性为string类型时有效。如果您尝试设置类似Content属性(typeof(object))的内容,则需要使用自定义StringFormatConverterlike here),并将格式字符串作为ConverterParameter

修改更新的问题

因此,如果您的ViewModel定义了精确度,我建议您将其作为MultiBinding,并创建自己的IMultiValueConverter。这在实践中非常烦人,从简单的绑定转变为需要扩展到MultiBinding的绑定,但如果在编译时不知道精度,那么这就是你所能做的。您的IMultiValueConverter需要获取值和精度,并输出格式化的字符串。您可以使用String.Format执行此操作。

但是,对于ContentControl之类的内容,您可以使用Style轻松完成此操作:

<Style TargetType="{x:Type ContentControl}">
    <Setter Property="ContentStringFormat" 
            Value="{Binding Resolution, StringFormat=N{0}}" />
</Style>

任何公开ContentStringFormat的控件都可以像这样使用。不幸的是,TextBox没有类似的内容。

答案 1 :(得分:6)

在给出0.299的输入时,接受的答案在整数位置不显示0。它在WPF UI中显示.3。所以我建议使用以下字符串格式

<TextBox Text="{Binding Value,  StringFormat={}{0:#,0.0}}" 

答案 2 :(得分:-2)

    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;
        }
    }