用于测量单位的wpf字符串格式c#

时间:2019-02-20 13:59:51

标签: c# wpf mvvm string-formatting

我将MVVM模式与Entity Framework结合使用来创建应用。我有一个名为ScaleRange的实体,它具有以下属性:UpperRange(以克或毫克表示,整数类型),LowerRange(以克或毫克表示,整数类型)和Precision(以克或毫克表示,十进制类型)。我将所有属性以克形式保存在数据库中(或者应该吗?)。问题是当我需要在DataGrid中显示ScaleRange的列表时,所有属性都以克表示(因为数据是从数据库中提取的),并且在某些情况下,该值是0.0001(以克为单位),我更希望在其中毫克更好的外观(在这种情况下为0.1)。是否存在某种字符串格式,例如,如果值<0.01而不是以毫克为单位,否则以克为单位?

这是DataGrid的代码(目前可以正常运行)

<DataGrid Grid.Column="3" Grid.Row="1" Grid.RowSpan="4" AutoGenerateColumns="False" ItemsSource="{Binding Scale.Ranges}" IsReadOnly="True">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Upper range" Width="*" Binding="{Binding UpperRange, StringFormat={}{0}g}"></DataGridTextColumn>
            <DataGridTextColumn Header="Lower range" Width="*" Binding="{Binding LowerRange, StringFormat={}{0}g}"></DataGridTextColumn>
            <DataGridTextColumn Header="Precision" Width="*" Binding="{Binding Precision, StringFormat={}{0}g}"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

2 个答案:

答案 0 :(得分:3)

我创建了此转换器,该转换器适用于单位前缀 G,M,K,m,μ,n

它还没有经过彻底的测试,所以让我知道任何问题,然后仔细检查一下您的值是否符合预期。

class GramToAppropriateUnitPrefixConverter : IValueConverter
{
    private List<string> unitsPrefix = new List<string>() //unit prefixes scalings by *10^3 in order, where the middle value is = *10^0
    {
        "G",
        "M",
        "k",
        "",
        "m",
        "μ",
        "n"
    };

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is double number)
        {
            string numAsString;
            int sigFigs = 3;
            string unit = "g";
            int noPrefixIndex = (unitsPrefix.Count / 2);
            int unitsPrefixIndex = noPrefixIndex;

            numAsString = number.ToString("G" + sigFigs.ToString()).Replace("+", ""); //Convert to $sigFigs number of significant figures
            string[] numberStandForm = numAsString.Split('E'); //Convert to standard form (number = [0] * 10^[1])

            if (numberStandForm.Count() == 2)
            {
                unitsPrefixIndex = noPrefixIndex +(int.Parse(numberStandForm[1]) / 3);

                //Check the index is not out the range of the list
                if (unitsPrefixIndex < 0)
                    unitsPrefixIndex = 0;
                else if (unitsPrefixIndex > unitsPrefix.Count - 1)
                    unitsPrefixIndex = unitsPrefix.Count - 1;

                //Change the standard form number so it is in the form ->   number * 10^(multipul of 3)
                var power = int.Parse(numberStandForm[1]) + ((unitsPrefixIndex - noPrefixIndex) * 3);
                string numberStr = (double.Parse(numberStandForm[0]) * Math.Pow(10, power)).ToString();
            }

            numAsString = numberStandForm[0] + unitsPrefix[unitsPrefixIndex] + unit;

            return numAsString;
        }

        return Binding.DoNothing;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

答案 1 :(得分:0)

您可以为此使用转换器,here是快速概述。
Convert函数中,可以添加逻辑以确定该值是否小于0.1,然后进行相应的修改。
 您实际上并不需要ConvertBack函数,因为它是单向绑定。

如果让值转换器类从MarkupExtensionYourConverter : MarkupExtension, IValueConverter)派生并像这样覆盖ProvideValue函数

public override object ProvideValue(IServiceProvider serviceProvider)
{
     return this;
} 

您可以将XAML代码中的集成简化为{Binding Converter={conv:YourConverter},而不必首先将转换器定义为资源。
您还必须添加对转换器名称空间的引用,在我的示例中为conv:(例如xmlns:conv="clr-namespace:Content.Common.Converter")。