Usando String Format para mostrar decimal até 2 lugares ou inteiro simples

Eu tenho um campo de preço para exibir que às vezes pode ser 100 ou 100.99 ou 100.9, O que eu quero é exibir o preço em 2 casas decimais somente se os decimais são inseridos para esse preço, por exemplo, se seu 100 por isso só deve mostre 100 não 100.00 e se o preço é 100.2 deve mostrar 100.20 similarmente para 100.22 deve ser o mesmo. Eu pesquisei e encontrei alguns exemplos, mas eles não combinavam exatamente com o que eu queria:

// just two decimal places String.Format("{0:0.00}", 123.4567); // "123.46" String.Format("{0:0.00}", 123.4); // "123.40" String.Format("{0:0.00}", 123.0); // "123.00" 

Uma maneira deselegante seria:

 var my = DoFormat(123.0); 

Com DoFormat sendo algo como:

 public static string DoFormat( double myNumber ) { var s = string.Format("{0:0.00}", myNumber); if ( s.EndsWith("00") ) { return ((int)myNumber).ToString(); } else { return s; } } 

Não é elegante, mas funciona para mim em situações semelhantes em alguns projetos.

Desculpe por reativar essa pergunta, mas não encontrei a resposta correta aqui.

Na formatação de números, você pode usar 0 como um local obrigatório e # como um local opcional.

Assim:

 // just two decimal places String.Format("{0:0.##}", 123.4567); // "123.46" String.Format("{0:0.##}", 123.4); // "123.4" String.Format("{0:0.##}", 123.0); // "123" 

Você também pode combinar 0 com # .

 String.Format("{0:0.0#}", 123.4567) // "123.46" String.Format("{0:0.0#}", 123.4) // "123.4" String.Format("{0:0.0#}", 123.0) // "123.0" 

Para este método de formatação é sempre usado o CurrentCulture . Para algumas culturas . será alterado para,.

Este é um caso de uso de número flutuante de formatação comum.

Infelizmente, todas as strings de formato de uma letra incorporadas (por exemplo, F, G, N) não conseguirão isso diretamente.
Por exemplo, num.ToString("F2") sempre mostrará 2 casas decimais como 123.40 .

Você terá que usar o padrão 0.## mesmo que pareça um pouco detalhado.

Um exemplo de código completo:

 double a = 123.4567; double b = 123.40; double c = 123.00; string sa = a.ToString("0.##"); // 123.46 string sb = b.ToString("0.##"); // 123.4 string sc = c.ToString("0.##"); // 123 

experimentar

 double myPrice = 123.0; String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice); 

Pergunta antiga, mas eu queria adicionar a opção mais simples na minha opinião.

Sem separadores de milhares:

 value.ToString(value % 1 == 0 ? "F0" : "F2") 

Com separadores de milhares:

 value.ToString(value % 1 == 0 ? "N0" : "N2") 

O mesmo, mas com String.Format :

 String.Format(value % 1 == 0 ? "{0:F0}" : "{0:F2}", value) // Without thousands separators String.Format(value % 1 == 0 ? "{0:N0}" : "{0:N2}", value) // With thousands separators 

Se você precisar em muitos lugares , eu usaria essa lógica em um método de extensão :

 public static string ToCoolString(this decimal value) { return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;) } 

Eu não sei de qualquer maneira para colocar uma condição no especificador de formato, mas você pode escrever seu próprio formatador:

 using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { // all of these don't work Console.WriteLine("{0:C}", 10); Console.WriteLine("{0:00.0}", 10); Console.WriteLine("{0:0}", 10); Console.WriteLine("{0:0.00}", 10); Console.WriteLine("{0:0}", 10.0); Console.WriteLine("{0:0}", 10.1); Console.WriteLine("{0:0.00}", 10.1); // works Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9)); Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9.1)); Console.ReadKey(); } } class MyFormatter : IFormatProvider, ICustomFormatter { public string Format(string format, object arg, IFormatProvider formatProvider) { switch (format.ToUpper()) { case "CUSTOM": if (arg is short || arg is int || arg is long) return arg.ToString(); if (arg is Single || arg is Double) return String.Format("{0:0.00}",arg); break; // Handle other default: try { return HandleOtherFormats(format, arg); } catch (FormatException e) { throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e); } } return arg.ToString(); // only as a last resort } private string HandleOtherFormats(string format, object arg) { if (arg is IFormattable) return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture); if (arg != null) return arg.ToString(); return String.Empty; } public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) return this; return null; } } } 

Código de linha simples:

 public static string DoFormat(double myNumber) { return string.Format("{0:0.00}", myNumber).Replace(".00",""); } 

Aqui está uma alternativa ao método de Uwe Keim, que ainda manteria o mesmo método:

 var example1 = MyCustomFormat(123.1); // Output: 123.10 var example2 = MyCustomFormat(123.95); // Output: 123.95 var example3 = MyCustomFormat(123); // Output: 123 

Com MyCustomFormat sendo algo como:

 public static string MyCustomFormat( double myNumber ) { var str (string.Format("{0:0.00}", myNumber)) return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str; } 

Temo que não haja um formato interno que faça isso. Você terá que usar um formato diferente, dependendo se o valor é um número inteiro ou não. Ou sempre formate em duas casas decimais e depois manipule a seqüência para remover qualquer “.00” à direita.

Se nenhuma das outras respostas funcionar para você, pode ser porque você está vinculando o ContentProperty de um controle na function OnLoad , o que significa que isso não funcionará:

 private void UserControl_Load(object sender, RoutedEventArgs e) { Bind.SetBindingElement(labelName, String.Format("{0:0.00}", PropertyName), Label.ContentProperty) } 

A solução é simples: existe uma propriedade ContentStringFormat no xaml. Então, quando você criar o label, faça isso:

 //if you want the decimal places definite  

Ou

 //if you want the decimal places to be optional  

algo assim também funciona:

 String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "") 

String.Format (“{0: 0.00}”, Convert.ToDecimal (totalPrice))

Para tornar o código mais claro que Kahia escreveu (é claro, mas fica complicado quando você quer adicionar mais texto a ele) … tente esta solução simples.

 if (Math.Round((decimal)user.CurrentPoints) == user.CurrentPoints) ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0}",user.CurrentPoints); else ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0.0}",user.CurrentPoints); 

Eu tive que adicionar o casting extra (decimal) para ter Math.Round comparar as duas variables ​​decimais.

Se o seu programa precisar ser executado rapidamente, chame value.ToString (formatString) para um desempenho de formatação de strings 35% mais rápido em relação a $ “{value: formatString}” e string.Format (formatString, value).

Dados

Desempenho de Formatação de C # String - VS2017 15.4.5

Código

 using System; using System.Diagnostics; public static class StringFormattingPerformance { public static void Main() { Console.WriteLine("C# String Formatting Performance"); Console.WriteLine("Milliseconds Per 1 Million Iterations - Best Of 5"); long stringInterpolationBestOf5 = Measure1MillionIterationsBestOf5( (double randomDouble) => { return $"{randomDouble:0.##}"; }); long stringDotFormatBestOf5 = Measure1MillionIterationsBestOf5( (double randomDouble) => { return string.Format("{0:0.##}", randomDouble); }); long valueDotToStringBestOf5 = Measure1MillionIterationsBestOf5( (double randomDouble) => { return randomDouble.ToString("0.##"); }); Console.WriteLine( $@" $""{{value:formatString}}"": {stringInterpolationBestOf5} ms string.Format(formatString, value): {stringDotFormatBestOf5} ms value.ToString(formatString): {valueDotToStringBestOf5} ms"); } private static long Measure1MillionIterationsBestOf5( Func formatDoubleUpToTwoDecimalPlaces) { long elapsedMillisecondsBestOf5 = long.MaxValue; for (int perfRunIndex = 0; perfRunIndex < 5; ++perfRunIndex) { var random = new Random(); var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < 1000000; ++i) { double randomDouble = random.NextDouble(); formatDoubleUpToTwoDecimalPlaces(randomDouble); } stopwatch.Stop(); elapsedMillisecondsBestOf5 = Math.Min( elapsedMillisecondsBestOf5, stopwatch.ElapsedMilliseconds); } return elapsedMillisecondsBestOf5; } } 

Saída de código

 C# String Formatting Performance Milliseconds Per 1 Million Iterations - Best Of 5 $"{value:formatString}": 419 ms string.Format(formatString, value): 419 ms value.ToString(formatString): 264 ms 

Referências

Cadeias de formato numérico personalizado [docs.microsoft.com]

Qt Charts BarChart Exemplo [doc.qt.io]

Isso funcionou para mim!

 String amount= "123.0000"; String.Format("{0:0.##}", amount); // "123.00"