6

我正在尝试为将在 MSN Messenger 上运行的 C# 应用程序创建文本列。我很难让一切都排队。

这是我想要的输出示例:

1)  Pizza Hut                                            123 Fake St.
2)  Domino's Pizza                                       123 Fake St.
3)  The Cheesecake Cafe                                  123 Fake St.
4)  Capital Pizza & Steakhouse                           123 Fake St.
5)  Funky Pickle Pizza                                   123 Fake St.
6)  Boston Pizza                                         123 Fake St.
7)  Rose Bowl Rouge Lounge                               123 Fake St.
8)  Royal Pizza                                          123 Fake St.
9)  A Columbus Pizza & Donair Inc                        123 Fake St.

但因为它是可变宽度字体,所以显示如下:

1)  Pizza Hut                                        123 Fake St.
2)  Domino's Pizza                                   123 Fake St.
3)  The Cheesecake Cafe                                  123 Fake St.
4)  Capital Pizza & Steakhouse                               123 Fake St.
5)  Funky Pickle Pizza                                   123 Fake St.
6)  Boston Pizza                                     123 Fake St.
7)  Rose Bowl Rouge Lounge                               123 Fake St.
8)  Royal Pizza                                          123 Fake St.
9)  A Columbus Pizza & Donair Inc                    123 Fake St.

我尝试过使用 C# string.PadRight() 函数以及创建自己的函数来使用空格和制表符添加填充。两者都适用于固定宽度的字体,但会破坏可变宽度的字体。

有没有办法确定给定字体中字符串的宽度?

或者有人有其他建议吗?

4

4 回答 4

7

只需使用TextRenderer类。最简单的情况:

Size size = TextRenderer.MeasureText("Hello world", someFont);

如果您无权访问 System.Windows.Fonts Graphics.MeasureString仍然存在,它有一些限制,但应该可以完成工作:

Bitmap bmp = new Bitmap(1,1);
Graphics graphics = Graphics.FromImage(bmp);
SizeF size = graphics.MeasureString("Hello world", someFont);

但请注意,如果您的文本字体和空格必须相同,则会出现无法完美对齐文本的情况。我不知道 MSN Messenger 在您的情况下能做什么,但除非您至少可以访问 HTML 的子集,否则您将无法获得完美的输出。

您还应该知道,如果您在本地计算机上进行测量并发送到另一台没有安装正确字体的列,您的列将不再看起来像列,因此您仅限于所有计算机上存在的基本字体子集。

如果多操作系统支持也是一项要求,您将遇到一些大问题,因为 Mac 和 PC 上的 Arial 字体看起来(和测量)并不完全相同。

于 2009-03-02T22:29:30.540 回答
0

您可以尝试使用 Graphics 类来测量给定特定字体的字符串的长度,然后使用它来确定要使用多少个选项卡。

于 2009-03-02T22:27:45.723 回答
0

看起来您正试图在单个文本字段中以 ASCII 格式呈现这一切。是的?如果是这样的话,那就太棘手了。看起来你现在每个标签后面都有固定数量的标签,这就是问题所在。您可以改为使用空格 - 我怀疑您正在使用 padright (不太熟悉该特定功能)。

然而,关键是,像这样的纯 ASCII,以可变宽度字体显示,你永远不会让它在第二列中完美排列。如果你勤奋,你可以把它弄得很近,但就是这样——如果你有一排有很多大写的 W,而另一排有很多小写的 i,那么无论你做什么,都会有很大的宽度差异。如果您在 GDI 中进行渲染,最好的方法是每列调用一次 DrawText。如果需要,您可以从每列中制作一个大字符串,然后在第一列上调用 MeasureString 以确定您需要为第二列移动多少空间。

或者,如果这是一个可以执行 html 的界面,表格或 div 会很好用。取决于您的环境的具体情况。如果这是 WinForms 等,您还可以在 FlowLayout 面板中设置两个自动高度设置标签等。有很多选项可以使这项工作正常工作,但不是纯 ascii 具有可变宽度字体。

编辑:另外,我看到您询问如何在 Web 服务中获取 Graphics 类实例。你可以这样做:

    private static Bitmap bitmap = new Bitmap( 1, 1 );
    private static Graphics graphics = null;

    public static Graphics GetGeneralGraphics()
    {
        if ( graphics == null )
            graphics = Graphics.FromImage( bitmap );
        return graphics;
    }

您可能希望在 Web 服务上下文中创建这些局部变量(完成后正确处理)。

于 2009-03-03T07:17:21.177 回答
-1

您可能应该在 HTML 中格式化所有内容,然后您可以为列输出 TABLE 和 TR/TD 元素

于 2009-03-02T22:28:33.540 回答