Drawing a Rectangle in the C# Console






4.33/5 (6 votes)
Draw rectangles in a C# console window with this drop-in class
Tip/Trick: Draw Boxes in a C# Console with this Drop-in Class
This is a drop-in class that allows the drawing of rectangles in a console window. I originally built it for my own needs but decided to share it for others that might need it.
Two different drawing modes are supported:
- WriteLine() Output Style - The function for this is
RectangleFromCursor(...)
. When a new box needs to be drawn on some new appended lines, similar to howWriteLine()
performs, then this function can be used. It basically callsWriteLine()
repeatedly to draw the new box. One drawback to theWriteLine()
version is that multiple rectangles cannot be drawn on the same line. For this, theOverwrite
style is needed. - Overwrite Style -
RectangleFromTop(...)
andRectangle(...)
do not useWriteLine()
. Instead they set the cursor to a specific location and then write. These functions are best utilized when a rectangle needs to be drawn in a specific location of the console window. If several boxes need to be on the same row, then these functions will serve best. Theoverwrite
style has two types:- Draw below offset 0,0 - When using
Rectangle(...)
, use theDrawKind.FromTop
option for this. It will draw based on the top of the console buffer area. Basically, if you scroll to the top, 0,0 is the top left corner. - Draw below offset of cursor - Use
DrawKind.BelowCursor
orDrawKind.BelowCursor
ButKeepCursorLocation
for this. This will draw the rectangles using the cursor row as an offset.
- Draw below offset 0,0 - When using
Code Features
When building the rectangle drawing class, I tried to make it as flexible as possible.
- It can draw single or double boarder boxes
- Draw boxes in different colors
- It restores the original draw color of the curser when done
- Supports writing from the top of the window or for appending at the curser
- Option to keep the curser at end of the rectangle or it can be returned to the original location
Example Usage
Here is some example code...
Console.WriteLine();
Console.WriteLine("01234567890123456789");
// Test 1: draw 2 x 2 square at 1,1
Draw.RectangleFromCursor(1, 0, 2, 2);
Console.WriteLine(" <--Cursor after test 1 was here.");
// Test 2: draw a yellow 2 x 2 square at 4,2
Draw.RectangleFromTop(4, 2, 2, 2, ConsoleColor.DarkYellow);
Console.WriteLine(" <--Cursor after test 2 was here.");
// Test 3: draw a red 2 x 2 square below
Draw.RectangleFromCursor(1, 3, 2, 2, keepOriginalCursorLocation: true, color: ConsoleColor.Red);
Console.WriteLine(" <--Cursor after test 3 was here.");
// Test 4: draw a green 2 x 2 square below
Draw.Rectangle(4, 2, 2, 2, Draw.DrawKind.BelowCursorButKeepCursorLocation, color: ConsoleColor.Green);
Console.WriteLine(" <--Cursor after test 4 was here.");
// Test 5: draw a double-boarder cyan rectangle around everything
Draw.RectangleFromTop(0, 0, 33, 15, ConsoleColor.Cyan, useDoubleLines: true);
Console.WriteLine(" <--Cursor after test 5 was here.");
The output of the above looks like this:
The Code (Drop-in Class)
Since the class is not too large, it is being posted here in its entirety. Just drop this in your console project and enjoy.
public static class Draw
{
/// <summary>
/// Draws a rectangle in the console using several WriteLine() calls.
/// </summary>
/// <param name="width">The width of the rectangle.</param>
/// <param name="height">The right of the rectangle.</param>
/// <param name="xLocation">The left side position.</param>
/// <param name="yLocation">The top position.</param>
/// <param name="keepOriginalCursorLocation">If true,
/// the cursor will return back to the starting location.</param>
/// <param name="color">The color to use. null=uses current color Default: null</param>
/// <param name="useDoubleLines">Enables double line boarders. Default: false</param>
public static void RectangleFromCursor(int width,
int height,
int xLocation = 0,
int yLocation = 0,
bool keepOriginalCursorLocation = false,
ConsoleColor? color = null,
bool useDoubleLines = false)
{
{
// Save original cursor location
int savedCursorTop = Console.CursorTop;
int savedCursorLeft = Console.CursorLeft;
// if the size is smaller then 1 then don't do anything
if (width < 1 || height < 1)
{
return;
}
// Save and then set cursor color
ConsoleColor savedColor = Console.ForegroundColor;
if (color.HasValue)
{
Console.ForegroundColor = color.Value;
}
char tl, tt, tr, mm, bl, br;
if (useDoubleLines)
{
tl = '+'; tt = '-'; tr = '+'; mm = '¦'; bl = '+'; br = '+';
}
else
{
tl = '+'; tt = '-'; tr = '+'; mm = '¦'; bl = '+'; br = '+';
}
for (int i = 0; i < yLocation; i++)
{
Console.WriteLine();
}
Console.WriteLine(
string.Empty.PadLeft(xLocation, ' ')
+ tl
+ string.Empty.PadLeft(width-1, tt)
+ tr);
for (int i = 0; i < height; i++)
{
Console.WriteLine(
string.Empty.PadLeft(xLocation, ' ')
+ mm
+ string.Empty.PadLeft(width - 1, ' ')
+ mm);
}
Console.WriteLine(
string.Empty.PadLeft(xLocation, ' ')
+ bl
+ string.Empty.PadLeft(width - 1, tt)
+ br);
if (color.HasValue)
{
Console.ForegroundColor = savedColor;
}
if (keepOriginalCursorLocation)
{
Console.SetCursorPosition(savedCursorLeft, savedCursorTop);
}
}
}
/// <summary>
/// Draws a rectangle in a console window using the top line of the buffer as the offset.
/// </summary>
/// <param name="xLocation">The left side position.</param>
/// <param name="yLocation">The top position.</param>
/// <param name="width">The width of the rectangle.</param>
/// <param name="height">The right of the rectangle.</param>
/// <param name="color">The color to use. null=uses current color Default: null</param>
public static void RectangleFromTop(
int width,
int height,
int xLocation = 0,
int yLocation = 0,
ConsoleColor? color = null,
bool useDoubleLines = false)
{
Rectangle(width, height, xLocation, yLocation, DrawKind.FromTop, color, useDoubleLines);
}
/// <summary>
/// Specifies if the draw location should be based on the current cursor location or the
/// top of the window.
/// </summary>
public enum DrawKind
{
BelowCursor,
BelowCursorButKeepCursorLocation,
FromTop,
}
/// <summary>
/// Draws a rectangle in the console window.
/// </summary>
/// <param name="width">The width of the rectangle.</param>
/// <param name="height">The right of the rectangle.</param>
/// <param name="xLocation">The left side position.</param>
/// <param name="yLocation">The top position.</param>
/// <param name="drawKind">Where to draw the rectangle and
/// where to leave the cursor when finished.</param>
/// <param name="color">The color to use. null=uses current color Default: null</param>
/// <param name="useDoubleLines">Enables double line boarders. Default: false</param>
public static void Rectangle(
int width,
int height,
int xLocation = 0,
int yLocation = 0,
DrawKind drawKind = DrawKind.FromTop,
ConsoleColor? color = null,
bool useDoubleLines = false)
{
// if the size is smaller then 1 than don't do anything
if (width < 1 || height < 1)
{
return;
}
// Save original cursor location
int savedCursorTop = Console.CursorTop;
int savedCursorLeft = Console.CursorLeft;
if (drawKind == DrawKind.BelowCursor || drawKind == DrawKind.BelowCursorButKeepCursorLocation)
{
yLocation += Console.CursorTop;
}
// Save and then set cursor color
ConsoleColor savedColor = Console.ForegroundColor;
if (color.HasValue)
{
Console.ForegroundColor = color.Value;
}
char tl, tt, tr, mm, bl, br;
if (useDoubleLines)
{
tl = '+'; tt = '-'; tr = '+'; mm = '¦'; bl = '+'; br = '+';
}
else
{
tl = '+'; tt = '-'; tr = '+'; mm = '¦'; bl = '+'; br = '+';
}
SafeDraw(xLocation, yLocation, tl);
for (int x = xLocation + 1; x < xLocation + width; x++)
{
SafeDraw(x, yLocation, tt);
}
SafeDraw(xLocation + width, yLocation, tr);
for (int y = yLocation + height; y > yLocation; y--)
{
SafeDraw(xLocation, y, mm);
SafeDraw(xLocation + width, y, mm);
}
SafeDraw(xLocation, yLocation + height + 1, bl);
for (int x = xLocation + 1; x < xLocation + width; x++)
{
SafeDraw(x, yLocation + height + 1, tt);
}
SafeDraw(xLocation + width, yLocation + height + 1, br);
// Restore cursor
if (drawKind != DrawKind.BelowCursor)
{
Console.SetCursorPosition(savedCursorLeft, savedCursorTop);
}
if (color.HasValue)
{
Console.ForegroundColor = savedColor;
}
}
private static void SafeDraw(int xLocation, int yLocation, char ch)
{
if (xLocation < Console.BufferWidth && yLocation < Console.BufferHeight)
{
Console.SetCursorPosition(xLocation, yLocation);
Console.Write(ch);
}
}
}