用于测量单位的 wpf 字符串格式 c#
wpf string format c# for measurement units
我将 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>
您可以为此使用一个转换器,here 是一个快速概览。
在 Convert
函数中,您可以添加逻辑来确定值是否 < 0.1 并相应地修改它。
您实际上并不需要 ConvertBack
函数,因为它是一种单向绑定。
如果让值转换器 class 派生自 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"
)。
我创建了这个适用于单位前缀 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();
}
}
我将 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>
您可以为此使用一个转换器,here 是一个快速概览。
在 Convert
函数中,您可以添加逻辑来确定值是否 < 0.1 并相应地修改它。
您实际上并不需要 ConvertBack
函数,因为它是一种单向绑定。
如果让值转换器 class 派生自 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"
)。
我创建了这个适用于单位前缀 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();
}
}