Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
.NET

How to Center a Menu in a C# Console Application

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Center a console menu by measuring the current window in character cells, calculating a zero-based column and row, then placing each line with Console.SetCursorPosition. Read Console.WindowWidth and Console.WindowHeight immediately before drawing; never assume an 80×25 terminal.

Center each menu line horizontally and vertically

This approach centers every line independently, so short and long entries can have different left edges:

string[] menuLines =
{
    "1. Start",
    "2. Settings",
    "3. Exit"
};

int width = Console.WindowWidth;
int height = Console.WindowHeight;
int startRow = Math.Max(0, (height - menuLines.Length) / 2);

Console.Clear();
for (int i = 0; i < menuLines.Length; i++)
{
    string line = menuLines[i];
    int left = Math.Max(0, (width - line.Length) / 2);
    int row = startRow + i;

    if (row >= height || left >= width)
        continue;

    Console.SetCursorPosition(left, row);
    Console.Write(line);
}

WindowWidth is the number of columns and WindowHeight is the number of rows. SetCursorPosition uses zero-based column and row coordinates; Microsoft documents that invalid coordinates can raise ArgumentOutOfRangeException.

Choose how horizontal alignment should work

Independent-line centering

Use (width - line.Length) / 2 for each line when the visual goal is to center every label itself. This is usually best for a simple list with no border.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common block centering

For a box or aligned menu, center the widest line once and pad every row to that width. The block then has one shared left and right edge:

using System.Linq;

string[] menuLines =
{
    "1. Start",
    "2. Settings",
    "3. Exit"
};

int menuWidth = menuLines.Max(s => s.Length);
int boxLeft = Math.Max(0, (Console.WindowWidth - menuWidth) / 2);
int boxTop = Math.Max(0, (Console.WindowHeight - menuLines.Length) / 2);

Console.Clear();
for (int i = 0; i < menuLines.Length; i++)
{
    string line = menuLines[i].PadRight(menuWidth);
    int row = boxTop + i;

    if (row >= Console.WindowHeight)
        break;

    Console.SetCursorPosition(boxLeft, row);
    Console.Write(line);
}

PadRight adds trailing spaces until the requested total length; PadLeft does the same with leading spaces. If a string is already longer than the requested width, padding leaves it unchanged.

What the vertical calculation does

(height - menuLines.Length) / 2 leaves approximately equal blank space above and below the menu. Math.Max(0, ...) prevents a negative row when the menu has more lines than the terminal. In a very short window, the menu therefore starts at row zero and may extend beyond the visible area; the bounds check stops drawing once the last row is reached.

Handle terminal resizing safely

Window dimensions can change between draws. Put the rendering code in a method and call it after a resize or after an action that returns to the menu. Re-read both dimensions each time rather than caching them for the lifetime of the program.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
static void DrawMenu(string[] menuLines)
{
    int width = Console.WindowWidth;
    int height = Console.WindowHeight;
    int top = Math.Max(0, (height - menuLines.Length) / 2);

    Console.Clear();
    for (int i = 0; i < menuLines.Length; i++)
    {
        int row = top + i;
        if (row >= height)
            break;

        string line = menuLines[i];
        int left = Math.Max(0, (width - line.Length) / 2);
        if (left >= width)
            continue;

        Console.SetCursorPosition(left, row);
        Console.Write(line);
    }
}

If the terminal is resized while the loop is running, a previously valid coordinate can become invalid. Catch ArgumentOutOfRangeException when your application must recover from such a race, then clear and redraw using fresh dimensions.

Redirected output and other failure cases

  • Output is redirected: redirected streams do not behave like an interactive window. Console dimension properties or cursor operations can fail, including with IOException. Detect non-interactive output for programs that may run in pipelines and use plain, non-positioned text instead.
  • The menu is wider than the window: the arithmetic clamps the left position to zero, but the line can still wrap or be clipped by the terminal. Consider shortening labels, wrapping them deliberately, or requiring a wider window.
  • The menu is taller than the window: the top row becomes zero and the bounds check draws only visible rows. A paging or scrolling design is needed if every option must remain accessible.
  • Coordinates are invalid: always check the calculated row and column before calling SetCursorPosition; its API uses zero-based coordinates and can reject values outside the available buffer.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Unicode and display-width caveat

string.Length counts UTF-16 code units, not terminal display cells. Combining marks may occupy no additional cell, while some wide glyphs occupy two. Consequently, arithmetic based on Length can look off-center for menus containing certain non-ASCII characters. For those menus, calculate each line’s terminal display width with a Unicode-aware routine and use that width for centering; continue passing the resulting cell coordinates to the console APIs.

Quick implementation checklist

  • Store the menu as a string[] and decide whether lines or the whole block should be centered.
  • Read Console.WindowWidth and Console.WindowHeight immediately before rendering.
  • Calculate a zero-based column and row, clamping the row and column to zero.
  • Check bounds before every SetCursorPosition call.
  • Use PadRight (or PadLeft) when rows need a common width.
  • Redraw after a resize or other event that may change the available dimensions.
  • Provide a non-positioned fallback for redirected or non-interactive output.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.