variable decimal places in .Net string formatters?

Use NumberFormatInfo:

Console.WriteLine(string.Format(new NumberFormatInfo() { NumberDecimalDigits = 2 }, "{0:F}", new decimal(1234.567)));
Console.WriteLine(string.Format(new NumberFormatInfo() { NumberDecimalDigits = 7 }, "{0:F}", new decimal(1234.5)));

The string to format doesn't have to be a constant.

int numberOfDecimalPlaces = 2;
string formatString = String.Concat("{0:F", numberOfDecimalPlaces, "}");
String.Format(formatString, 654.321);

Another option is using interpolated strings like this:

int prec = 2;
string.Format($"{{0:F{prec}}}", 654.321);

Still a mess, but yet more convenient IMHO. Notice that string interpolation replaces double braces, like {{, with a single brace.