String.Format() 的对齐方式在 MessageBox 中表现不同
String.Format()'s alignment behaves different when it comes to MessageBox
我正在使用 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);
控制台结果如下图
但是,当我尝试在 MessageBox 上显示它时,列在移动。不知何故空间被吞没了。
MessageBox.Show(result, "MBox Test");
也还行,因为我对.Net的"MessageBox"class不是很跪。它有很多限制。
所以我决定实现一个自定义表单来显示这条消息。我试过使用 Label 和 RichTextBox。但不幸的是,结果与 MessageBox 完全相同。
我很困惑。为什么.Net自带的控件不支持String.Format()的对齐。我有什么办法可以处理这种情况吗?
控制台使用monospaced font,而消息框使用可变宽度字体。这就是消息框中似乎没有保留对齐方式的原因。
在控制台中,space 与任何其他字符的宽度相同。在消息框中,space 没有那么宽("i" 和 "l" 之类的字符也没有那么宽),所以事情不会按照您希望的方式排列。
最接近于在消息框中保持对齐的方法是使用制表符而不是 spaces,但即便如此,由于某些制表符的长度,可能无法对齐单词。
String.Format(...)
工作得很好,但由于字体的原因,它在您的消息框中与 table 不对齐!
在您的控制台中,您使用的是固定宽度 (monospace) 的字体,但消息框使用的是动态宽度的字体。因此,例如"M" 比 "i" 或 " " (space) 消耗更多 space,这会弄乱您的布局。
作为 you can't change the messagebox font,您必须使用支持自定义字体的任何类型的文本小部件创建自己的框架,例如 TextBox
或只是一个普通的 Label
.
您可以使用制表符 (\t) 而不是空格来获得相同的列间距,它应该适用于每种字体类型:)
在紧要关头,在每列之后使用制表符可能会奏效,但效果很差。
//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());
这会产生:
我为此苦苦挣扎了一段时间,这就是我解决这个问题的方法:
string messageBoxText = "";
messageBoxText += "'Text 1'".PadRight(40) + "\t" + "text2" + "\n";
messageBoxText += "'Long Text 3'".PadRight(40) +"\t" + "text4" + "\n";
MessageBox.Show(messageBoxText);
您将在 MessageBox 中获得此格式化字符串,关键是在右填充文本后添加 \t
。
我正在使用 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);
控制台结果如下图
但是,当我尝试在 MessageBox 上显示它时,列在移动。不知何故空间被吞没了。
MessageBox.Show(result, "MBox Test");
也还行,因为我对.Net的"MessageBox"class不是很跪。它有很多限制。
所以我决定实现一个自定义表单来显示这条消息。我试过使用 Label 和 RichTextBox。但不幸的是,结果与 MessageBox 完全相同。
我很困惑。为什么.Net自带的控件不支持String.Format()的对齐。我有什么办法可以处理这种情况吗?
控制台使用monospaced font,而消息框使用可变宽度字体。这就是消息框中似乎没有保留对齐方式的原因。
在控制台中,space 与任何其他字符的宽度相同。在消息框中,space 没有那么宽("i" 和 "l" 之类的字符也没有那么宽),所以事情不会按照您希望的方式排列。
最接近于在消息框中保持对齐的方法是使用制表符而不是 spaces,但即便如此,由于某些制表符的长度,可能无法对齐单词。
String.Format(...)
工作得很好,但由于字体的原因,它在您的消息框中与 table 不对齐!
在您的控制台中,您使用的是固定宽度 (monospace) 的字体,但消息框使用的是动态宽度的字体。因此,例如"M" 比 "i" 或 " " (space) 消耗更多 space,这会弄乱您的布局。
作为 you can't change the messagebox font,您必须使用支持自定义字体的任何类型的文本小部件创建自己的框架,例如 TextBox
或只是一个普通的 Label
.
您可以使用制表符 (\t) 而不是空格来获得相同的列间距,它应该适用于每种字体类型:)
在紧要关头,在每列之后使用制表符可能会奏效,但效果很差。
//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());
这会产生:
我为此苦苦挣扎了一段时间,这就是我解决这个问题的方法:
string messageBoxText = "";
messageBoxText += "'Text 1'".PadRight(40) + "\t" + "text2" + "\n";
messageBoxText += "'Long Text 3'".PadRight(40) +"\t" + "text4" + "\n";
MessageBox.Show(messageBoxText);
您将在 MessageBox 中获得此格式化字符串,关键是在右填充文本后添加 \t
。