Я использую String.Format () для форматирования некоторой текстовой информации, и он отлично работает с «Console.WriteLine ()», как описано в msdn.

Мой код такой:

        StringBuilder strBuilder = new StringBuilder();
        strBuilder.AppendLine("Summary Information:");
        strBuilder.AppendFormat("{0,-10}{1,-8}{2,-10}{3,-30}{4,-7}\n", "Header1", "Header2", "Header3", "Header4", "Header5");
        strBuilder.AppendFormat("{0,-10}{1,-8}{2,-10}{3,-30}{4,-7}\n\n", "A", "1", "Y", "Long Information", "13");
        string result = strBuilder.ToString();

        Console.WriteLine(result);

Результат консоли показан ниже.

Console Result

Но когда я пытаюсь показать это в MessageBox, столбцы меняются. Как-то проглатываются пробелы.

 MessageBox.Show(result, "MBox Test");

MessageBox result

Это также нормально, потому что я не особо преклонялся перед классом MessageBox в .Net. У него так много ограничений.

Поэтому я решил реализовать настраиваемую форму для отображения этого сообщения. Я пробовал с Label и RichTextBox. Но, к сожалению, результат был точно таким же, как у MessageBox.

И я сбит с толку. Почему собственные элементы управления .Net не могут поддерживать выравнивание String.Format (). Как я могу справиться с этой ситуацией?

4
fkucuk 27 Апр 2016 в 08:34

4 ответа

Лучший ответ

String.Format(...) работает отлично, но он не выравнивается как таблица в вашем окне сообщения из-за шрифта!

В консоли вы используете шрифт фиксированной ширины (моноширинный), но в окне сообщений используется шрифт с динамической шириной. Поэтому, например, буква «M» занимает больше места, чем «i» или «» (пробел), и это нарушает ваш макет.

Поскольку вы не можете изменить шрифт окна сообщений, вы должны создать свой собственный фрейм с любым текстовым виджетом, который поддерживает настраиваемые шрифты, например TextBox или просто обычный Label.

1
Community 23 Май 2017 в 12:34

В крайнем случае, использование вкладок после каждого столбца может сработать, но очень удачно.

//I'm using Tuple Types and Interpolated Strings which are available in C# 7 and .NET 4.7+
(int, int, int) maxFieldLengths = (10, 10, 10); //Use 10 as the min length
List<(string, string, string)> values = new List<(string, string, string)>();
values.Add(("header1", "header2", "header3"));
values.Add(("value1", "value2", "value3"));
values.Add(("longerstringvalue", "value4", "evenlongerstringvaluehere"));

foreach (var value in values)
{
    maxFieldLengths.Item1 = Math.Max(maxFieldLengths.Item1, value.Item1.Length);
    maxFieldLengths.Item2 = Math.Max(maxFieldLengths.Item2, value.Item2.Length);
    maxFieldLengths.Item3 = Math.Max(maxFieldLengths.Item3, value.Item3.Length);
}

var messageBuilder = new StringBuilder();
foreach (var value in values)
{
    messageBuilder.AppendFormat($"{{0,{maxFieldLengths.Item1 * -1}}}\t| {{1,{maxFieldLengths.Item2 * -1}}}\t| {{2,{maxFieldLengths.Item3 * -1}}}{Environment.NewLine}",
        value.Item1, value.Item2, value.Item3);
}
MessageBox.Show(messageBuilder.ToString());

Это производит:

messagebox

0
Sal 30 Окт 2019 в 15:20

Вы можете использовать табуляции (\ t) вместо пробелов, чтобы получить одинаковые расстояния между столбцами, это должно отлично работать с каждым типом шрифта :)

0
zbwr-the-mighty 27 Апр 2016 в 05:51

В консоли используется моноширинный шрифт, тогда как в окне сообщения используется шрифт переменной ширины. Вот почему кажется, что выравнивание не сохраняется в окне сообщения.

В консоли пробел такой же ширины, как и любой другой символ. В окне сообщения пространство не такое широкое (как и символы типа «i» и «l»), поэтому вещи не совпадают так, как вы хотите.

Самое близкое, что вы сможете сделать, чтобы сохранить выравнивание в окне сообщения, - это использовать табуляцию вместо пробелов, но даже тогда вещи могут не совпадать из-за длины некоторых слов.

3
reduckted 27 Апр 2016 в 05:45