How to format a string displayed in a MessageBox in C#?

21,929

Solution 1

Try something like this:

string strMsg = String.Format("Machine\t: {0}\nUser\t: {1}", "TestMachine", "UserName");

Edited: Gotta have that String.Format there or that lone bracket at the end is sad.

Solution 2

The reason for this is that the message box is displayed in a font where Machine and User may not be the same length.

You could try the following:

"Machine\t:" + "TestMahine" + "\r\n" +
"User\t:" + "UserName";

The \t character will probably correctly align your colons.

Solution 3

In a WPF (or WinForms, or Java, or Qt, or whatever) TextBlock, if you want characters to be aligned, you need to use a fixed font length, in order for every character to have the same length than the others.

i.e. Use a font like "Courier New" or "Monospaced" or "Consolas".

In a MessageBox, you cannot control the font-family. If you really want this feature, did you consider creating a customized Window component ? Like this...

<Window x:Class="WpfApplication1.CustomMessageBox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        SizeToContent="WidthAndHeight" MaxWidth="500">

    <Grid Margin="10">
        <TextBlock FontFamily="Courier New" Text="{Binding Message}" />
    </Grid>

</Window>  

.

public partial class CustomMessageBox : Window, INotifyPropertyChanged {
    private string message;
    public string Message {
        get { return message; }
        set { message = value; RaisePropertyChanged("Message"); }
    }

    public CustomMessageBox() {
        InitializeComponent();
        DataContext = this;
    }

    public static void Show(string title, string message) {
        var mbox = new CustomMessageBox();
        mbox.Title = title;
        mbox.Message = message;
        mbox.ShowDialog();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string property) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

As a result, you can invoke your new messagebox with:

string strMsg = 
    "Machine  : " + "TestMahine" + "\r\n" +
    "User     : " + "UserName";

CustomMessageBox.Show("Hello !", strMsg);

Of course, you will need to do some little arrangements to your custom message box view but you got the idea ;-)

Solution 4

I ran into the same problem trying to align data in a MessageBox and after searching for a while I decided to write my own method using TextRenderer.MeasureText to get measurements at the pixel level. The method takes two parameters; the first is the string to format and the second is the longest string to be shown to the left of the colon (the alignment character in this example). What the method is doing is prepending blank spaces until the string reaches, but does not exceed, the length of the longest string. The method is called as shown below where "Department: " is the longest string.

StringBuilder sb = new StringBuilder();
string longest = "Department:  ";
sb.AppendLine(StringLengthFormat("Result(s):  ", longest) + results);

The actual method that does the formatting is:

private string StringLengthFormat(string inString, string longest)
{
    Size textSizeMax = TextRenderer.MeasureText(longest, System.Drawing.SystemFonts.DefaultFont);
    Size textSizeCurrent = TextRenderer.MeasureText(inString, System.Drawing.SystemFonts.DefaultFont);
    do
    {
        inString = " " + inString;
        textSizeCurrent = TextRenderer.MeasureText(inString, System.Drawing.SystemFonts.DefaultFont);
    } while (textSizeCurrent.Width < textSizeMax.Width);
    return inString;
}

Because I can also have one or more lines that do NOT start with the "description" followed by a colon but still need to be aligned I came up with a way to format those lines using the same method. I concatenate that data using the carriage return and tab characters "\r\t" and then replace the tab character "\t" with my method. Note that I include the two blank spaces that follow the colon in this example in order to give the formatting method something to prepend to and that I am trimming the trailing "\r\t" before formatting the string. The complete code section is shown below followed by a link to the example MessageBox output created by that code.

string results = "";
StringBuilder sb = new StringBuilder();
string longest = "Department:  ";
foreach (EncounterInfo enc in lei)
{
    results += enc.Description + " " + enc.ResultValue + " " + enc.ResultUnits + "\r\t";
}
results = results.TrimEnd(new char[] { '\r', '\t' });
results = results.Replace("\t", StringLengthFormat("  ", longest));
sb.AppendLine(StringLengthFormat("Result(s):  ", longest) + results);
sb.AppendLine(StringLengthFormat("Patient:  ", longest) + ei.PatientName);
sb.AppendLine(StringLengthFormat("Accession:  ", longest) + ei.AccessionNumber);
sb.AppendLine(longest + ei.CollectionClassDept);
sb.AppendLine();
sb.AppendLine("Continue?");
dr = MessageBox.Show(sb.ToString(), "Add to Encounters", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

Example MessageBox with string length formatting

Solution 5

Based on the approach specified by Terrence Meehan, I rewrote the StringLengthFormat method as follow:

using System.Drawing;
using System.Windows.Forms;

enum Alignment { Left = 0, Right = 1};

static string StringLengthFormat(string inputString, string longestString, 
                                          Alignment alignment=Alignment.Left, string margin="")
{
    Size textSizeMax = TextRenderer.MeasureText(longestString + margin, SystemFonts.MessageBoxFont);
    Size textSizeCurrent = TextRenderer.MeasureText(inputString, SystemFonts.MessageBoxFont);

    do
    {
        if (alignment == Alignment.Left)
        {
            inputString += " ";
        }
        else
        {
            inputString = " " + inputString;
        }

        textSizeCurrent = TextRenderer.MeasureText(inputString, SystemFonts.MessageBoxFont);
    } while (textSizeCurrent.Width < textSizeMax.Width);

    return inputString;
}

The differences are as follows:

  1. Instead of System.Drawing.SystemFonts.DefaultFont, I use System.Drawing.SystemFonts.MessageBoxFont;
  2. The parameter margin sets the distance between the columns (by transferring the required number of spaces);
  3. The parameter alignment sets the alignment in the columns (left or right). If desired, the code can be supplemented so that the center alignment option also appears.
Share:
21,929
Arvind Bhatt
Author by

Arvind Bhatt

Updated on July 09, 2022

Comments

  • Arvind Bhatt
    Arvind Bhatt almost 2 years

    I want to display a string in a message box with a following format:

    Machine : TestMachine User : UserName

    I am doing this:

    string strMsg = "Machine  :" + "TestMahine" + "\r\n" +
                    "User     :" + "UserName";
    

    MessageBox.Show(strMsg);

    When I do this the message box do not display a string as formated above. Colon(") dosen't keep alligned. The above format is also do not work in WPF TextBlock control.

    Please help!!