Introduction
The string format capabilities built into Visual Studio is somewhat limited; what if you want to actually display an infinity symbol instead of the word Infinity. It is not possible with the current string format (StringFormat
class
) capability.
Background
I wanted to handle formatting the case of when a double
value was equal to double.NaN
. Would have liked to have just extended the StringFormat
class
, but that class
is sealed
: The limitations within WPF strikes again. Was hoping maybe be able to use a MarkupExtension
, but that did not seem practical. Ended up using my standard backup, the IValueConverter
.
Using the Code
I only implemented the case for double, but obviously
could add the case for float
also. To make the converter work in the Binding
, the Path
is the path to a double value, the converter is this converter (inherited from MarkupExtension
so did not have to previously define the converter), and the format string
is passed in the ConverterParameter
:
<TextBlock Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Positive,
Converter={local:FormatConverter},
ConverterParameter=+0.0;(-0.0);—;+∞;-∞;§}" />
The code handles the following cases:
- Where there are two or less ";", (cases for positive, negative, and zero) then just uses the original format string.
- In the case of 3 ";", then the last format is used for any infinity or NaN values.
- In the case of 4 ";", then the 4th format is used for the two infinity cases, and the last format for the NaN case.
- In the case of 5 ";", then the 4th format is used for positive infinity, the fifth of negative infininty, and the last for NaN.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
var doubleValue = (double)value;
var formats = parameter.ToString().Split(';');
if (formats.Length < 4) return doubleValue.ToString(formats.ToString());
if (formats.Length == 4)
return (double.IsInfinity(doubleValue) || double.IsNaN(doubleValue))
? formats[3]
: doubleValue.ToString(string.Join(";", formats.Take(3).ToArray()));
if (formats.Length == 5)
return double.IsInfinity(doubleValue)
? formats[3]
: double.IsNaN(doubleValue)
? formats[4]
: doubleValue.ToString(string.Join(";", formats.Take(3).ToArray()));
else
return double.IsPositiveInfinity(doubleValue)
? formats[3]
: double.IsNegativeInfinity(doubleValue)
? formats[4]
: double.IsNaN(doubleValue)
? formats[5]
: doubleValue.ToString(string.Join(";", formats.Take(3).ToArray()));
}
if (value is string) return value;
throw new NotImplementedException($"Format for {targetType.Name} not implemented");
}
I added the string
case so that there would not be an issue when in design view.
The Sample
I basically used the XAML code above for each of the cases to create the sample. The control to the right has no special formatting, the control to the left used the FormatConverter
with a ConverterParameter
of "+0.0;(-0.0);—;+∞;-∞;§"
History
- 16/06/22: Initial version
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.