I'm using MVVM pattern with Entity Framework to create an app. I have an Entity called ScaleRange which has attributes: UpperRange (in grams or milligrams, integer type), LowerRange (in grams or milligrams, integer type) and Precision (in grams or milligrams, decimal type). I save all atributes in database in grams (or should I?). The problem is when I need to display the list of ScaleRange in DataGrid, all atributes are represented in grams (because the data was pulled from database) and there are some cases when the value is 0.0001 (in grams) which I prefer to be in milligrams for better look (0.1 in this case). Is there some kind of string format where for example if value < 0.01 than display in milligrams else display in grams?
Here is the code for DataGrid (which is working fine for now)
<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>
I've created this converter which works for the unit prefixes G, M, K, m, μ, n.
It hasn't been tested too thoroughly, so let me know of any issues and just double check your values are as expected.
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();
}
}