формат строки wpf c # для единиц измерения - PullRequest
0 голосов
/ 20 февраля 2019

Я использую шаблон MVVM с Entity Framework для создания приложения.У меня есть объект с именем ScaleRange, который имеет атрибуты: UpperRange (в граммах или миллиграммах, целочисленный тип), LowerRange (в граммах или миллиграммах, целочисленный тип) и Precision (в граммах или миллиграммах, десятичный тип).Я сохраняю все атрибуты в базе данных в граммах (или я должен?).Проблема в том, что когда мне нужно отобразить список ScaleRange в DataGrid, все атрибуты представлены в граммах (потому что данные были извлечены из базы данных), и в некоторых случаях значение равно 0,0001 (в граммах), в которых я предпочитаю находиться вмиллиграммы для лучшего взгляда (0.1 в этом случае).Существует ли какой-нибудь формат строки, где, например, если значение <0,01, чем отображается в миллиграммах, в противном случае отображается в граммах? </p>

Вот код для 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 голосов
/ 20 февраля 2019

Я создал этот конвертер, который работает для префиксов единиц измерения 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();
    }

}
0 голосов
/ 20 февраля 2019

Для этого можно использовать преобразователь, здесь - краткий обзор.
В функции Convert вы можете добавить свою логику, чтобы определить, является ли значение <0,1, и соответственно изменить ее.<br> Вам на самом деле не нужна функция ConvertBack, так как это односторонняя привязка.

Если вы позволите классу преобразователя значений наследоваться от MarkupExtension (YourConverter : MarkupExtension, IValueConverter) и переопределите ProvideValue функция, подобная этой

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

, вы можете упростить интеграцию в своем коде XAML до {Binding Converter={conv:YourConverter}, вместо того, чтобы сначала определять конвертер как ресурс.
Вы также должны добавить ссылку напространство имен конвертера, которое в моем примере conv: (например, xmlns:conv="clr-namespace:Content.Common.Converter").

...