格式化网格中的十进制值

时间:2015-04-03 12:27:46

标签: c# asp.net

我正在尝试为几个在DB中为十进制的检索字段实现自定义格式。我的价格字段中有1122.454540000这样的数据。我希望在自定义格式化之后在网格中显示。如果小数点后的前四个字段中的至少一个不为零,我想在小数点后显示四位数。如果我有像1122.000100这样的字段,我希望将其显示为1122.0001,但我的值为9876.000000,那么我只想显示没有任何小数点的9876。

目前一切正常
string.Format("{0:F4}", Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price")))

但我对一个特定案例有一个问题。当我获得1122.40001122.5400等值时,只显示1122.41122.54,而不是显示所有四位数,而不管最后的尾随数字是否为零。不知道我是否朝着正确的方向前进?

6 个答案:

答案 0 :(得分:1)

如果您希望42.0000001格式化42

可以修改以下解决方案。 但基本上,您只想从字符串中删除.00..

您可以使用RegEx执行此操作:

public string Format(string format, double value)
{
    var regex = new Regex(@"^(?<IntPart>.*)([.,]0*)$");
    var s = String.Format("{0:F4}", value);
    var match = regex.Match(s);
    if (match.Success)
    {
        return match.Groups["IntPart"].Value;
    }
    return s;
}

Console.WriteLine(Format("{0:F4}", 1.35687));    // 1.3569
Console.WriteLine(Format("{0:F4}", 1.35));       // 1.3500
Console.WriteLine(Format("{0:F4}", 1));          // 1
Console.WriteLine(Format("{0:F4}", 42.000001));  // 42

如果您希望42.0000001格式化为42.0000。

您需要测试值的小数部分(正好为0)。

我认为执行很好的唯一方法是使用ICustomFormatter

创建 F_XX 格式, F0 FXX ,具体取决于变量是否为整数与否。 (在您的情况下, F_4 F0 F4 )。

这是第一次尝试:

public class MyCustomFormatter : IFormatProvider, ICustomFormatter
{
    // Match "F_XX" where XX are digits.
    private readonly Regex _regex = new Regex("F_(?<DigitCount>\\d+)");

    // IFormatProvider.GetFormat implementation.
    public object GetFormat(Type formatType)
    {
        // Determine whether custom formatting object is requested.
        if (formatType == typeof(ICustomFormatter))
            return this;
        else
            return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        var shouldUseF0 = false;

        var match = _regex.Match(format);

        // Detect F_XX format.
        if (match.Success)
        {
            // Manage float.
            if (arg is float)
            {
                if (((float) arg)%1 == 0)
                {
                    shouldUseF0 = true;
                }
            }

            // Manage double.
            if (arg is double)
            {
                if (((double) arg)%1 == 0)
                {
                    shouldUseF0 = true;
                }
            }

            // TODO: Manage int, long...

            if (shouldUseF0)
            {
                format = "F0";
            }
            else
            {
                // Build the FXX format.
                format = "F" + match.Groups["DigitCount"].Value;
            }
        }

        if (arg is IFormattable) return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
        if (arg != null) return arg.ToString();
        return String.Empty;
    }
}

结果如下:

Console.WriteLine(String.Format(cf, "{0:F_4}", 1.35678));  // 1.3568
Console.WriteLine(String.Format(cf, "{0:F_4}", 1.35));     // 1.3500
Console.WriteLine(String.Format(cf, "{0:F_4}", 1.00));     // 1

答案 1 :(得分:0)

试试这个:

string.Format("{0:#.0000}", Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price")))

#代表任何数字,0代表0,如果没有数字或数字本身。
More on MSDN about the Custom Numeric formatting in .NET
不幸的是,如果你想为整数隐藏零,那么这种方法可能无法正常工作

Great article mentioned in other answer

  

设置固定数量的小数位数
  这与上面的示例类似,但我们的格式字符串中没有哈希('#'),我们是
  将使用零('0'),如下所示:

string.Format("{0:0.00}", 256.583); // "256.58"
string.Format("{0:0.00}", 256.586); // "256.59"
string.Format("{0:0.00}", 256.58);  // "256.58"
string.Format("{0:0.00}", 256.5);   // "256.50"
string.Format("{0:0.00}", 256.0);   // "256.00" - No luck here

<强>更新
正如我所说,如果数字在小数部分没有数字,那么这不会显示前导零,所以你可以在格式化之前用Math.Truncate方法检查:

var decimalValue = Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price"));
string.Format((decimalValue - Math.Truncate(decimalValue)) < 0.0001 ? "{0:#.####}" : {0:#.0000}", decimalValue)

但这会为您的计划带来巨大的开销。

答案 2 :(得分:0)

它很简单

  Math.Round(Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price")), 4).ToString("N4")
  

控制台示例

static void Main(string[] args)
    {

        Console.WriteLine(Math.Round(1122.454540000, 4).ToString("N4"));  // output 1122.4545
        Console.WriteLine(Math.Round(1122.000100, 4).ToString("N4")); // output 1122.0001
        Console.WriteLine(Math.Round(9876.000000, 4).ToString("N4"));// output 9876.0000
        Console.WriteLine(Math.Round(1122.4000, 4).ToString("N4"));// output 1122.4000
        Console.WriteLine(Math.Round(1122.5400, 4).ToString("N4"));// output 1122.5400
            Console.ReadLine();

    }

答案 3 :(得分:0)

如果可以采用某种解决方法,请尝试使用

   double price= 12.00300;
   string op = null;
   price= Double.Parse(string.Format("{0:0.0000}", value));
   if ((price % 1) != 0)
     op =   string.Format("{0:#.0000}", price);
   else
     op =  string.Format("{0}", price);
  

您可以像实用功能一样使用它,也可以根据需要进行更改。

  1. 对于12.000000 =&gt; 12
  2. 对于12.001000 =&gt; 12.0010
  3. 对于12.333333 =&gt; 12.3333

答案 4 :(得分:0)

您可以检查小数是否为整数,然后使用适当的格式。使用扩展方法的实现:

 public static class DecimalExtension
  {
    public static string MyFormat(this decimal value)
    {
       decimal rounded = Math.Round(value, 4);
       if ((rounded % 1) == 0)
       {
         return rounded.ToString("0:0");
       }

        return rounded.ToString("0:0.0000");

      }
  }

答案 5 :(得分:-1)

你可能想看看这个: http://www.daveoncsharp.com/2009/09/formatting-decimals-in-csharp/

具体是:

string.Format("{0:0.00}", 256.0);   // "256.00"