One possible solution would be to implement your own custom format provider, so that you can use the standard ToString
method of the rect object. In order to do this, you need to define a custom formatter class that implements the IFormatProvider interface and the ICustomFormatter interface. This ways you could implement your own ToString("D2")
solution. An example solution of the custom formatter for your needs can look like this:
public class CustomRectFormat : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
else
{
return null;
}
}
// the custom format
public string Format(string fmt, object arg, IFormatProvider formatProvider)
{
// the method processes every part of the Rect members
var chunk = arg.ToString();
// skip delimiters
if (chunk != ";")
{
// round doubles if possible
Double part = 0.0;
if (Double.TryParse(chunk, out part))
{
return Math.Round(part, 2).ToString();
}
}
return chunk;
}
}
Usage with the standard Rect.ToString
method:
var rect = new Rect();
rect.X = 0.5678;
rect.Width = 1.2345;
Console.WriteLine(rect.ToString(new CustomRectFormat()));
The output is as desired:
0,57;0;1,23;0
Another possible solution would be to implement your own Rect
wrapper class. Since Rect
is sealed, it can't be subclassed, but you can still create class that mimics the original class. In this class you can overwrite the ToString
method with rounding:
public class CustomRect
{
private Rect rect;
public CustomRect() : this(new Size(0.0, 0.0))
{
}
public CustomRect(Size size)
{
rect = new Rect(size);
}
public Double Width
{
get { return rect.Width; }
set { rect.Width = value; }
}
public Double X
{
get { return rect.X; }
set { rect.X = value; }
}
public Double Y
{
get { return rect.Y; }
set { rect.Y = value; }
}
public Double Height
{
get { return rect.Height; }
set { rect.Height = value; }
}
public String ToString()
{
return String.Format("{0};{1};{2};{3}", Math.Round(rect.X, 2), Math.Round(rect.Y, 2), Math.Round(rect.Width, 2), Math.Round(rect.Height));
}
}
Usage of the class:
var rect1 = new CustomRect();
var rect2 = new Rect();
rect1.X = 0.123;
rect1.Width = 3.2342342342342;
rect1.Height = 0.987234876234;
rect2.X = 0.123;
rect2.Width = 3.2342342342342;
rect2.Height = 0.987234876234;
Console.WriteLine(rect1.ToString());
Console.WriteLine(rect2.ToString());
And the output is:
0,12;0;3,23;1
0,123;0;3,2342342342342;0,987234876234
This solution has the problem, that you need to use everywhere the custom class and not the predefined Rect
class.
Another good approach would be to create (as suggested by @Flat Eric) an extension method that does this for all objects of the Rect
class. The downside of this approach is, that you can't use the ToString
method when needed.
You need to decide which solution is more suitable for you in this case.