如何在不裁剪的情况下使用 DrawString?

18

我认为DrawString函数截断整个字符或单词的方式很反直觉,显示文本的部分清晰地传达了某些内容缺失。

以下是一些例子:

StringTrimming.None: enter image description here

StringTrimming.Character: enter image description here

我想要的效果: enter image description here (GIMP模型)

StringTrimming.None和StringTrimming.Character是相同的吗?在我的情况下,它们似乎完全一样。我有没有忽视什么,还是这是一个已知的“特点”?

根据文档 StringTrimming.None “指定不进行修剪。”

此网站 使用Java创建的示例甚至显示“None”修剪比“Character”更多的字符。

还有其他技巧可以实现这种效果吗?

注意:我不想显示“…”或类似的内容。我认为这是一种浪费空间,但这可能是一个讨论UX的话题。


抱歉..只是想知道..你会将它应用到什么地方? - matzone
@Rotem 不错的想法,但在有足够垂直空间的情况下,这将破坏换行。不过,你应该把它作为一个答案添加进去。对于单行来说,它非常有效! - Sarien
@matzone DataGridView(对于不太熟悉Windows Forms的人来说,它是一个表格)。 - Sarien
@Sarien 我已经这样做了 :) 你能举个例子说明一下垂直空间吗?我不明白你所指的情况。 - Rotem
@Rotem 如果单元格非常高但对于文本来说太窄,DrawString通常会自动换行。当然,如果您在矩形的大小上撒谎,它就无法正确地完成这项工作了。 :) - Sarien
@Sarien 我猜你不喜欢默认的椭圆形,所以才这样做? - Justin
2个回答

14

这段文字可能看起来被剪裁了,因为它实际上隐式地换到了下一行。在调用Graphics.DrawString时,通过传递一个StringFormat对象并将其FormatFlags属性设置为NoWrap来禁用换行:

StringFormat format =
    new StringFormat
    {
        FormatFlags = StringFormatFlags.NoWrap,
        Trimming = StringTrimming.None
    };
g.DrawString(s, font, brush, rect, format);

1
有没有可能保留换行,只有在没有足够的空间容纳另一行时才禁用它?(我可以测量一切来做到这一点,但希望避免这样做。) - Sarien
1
@Sarien:似乎没有相应的标记,你需要使用“if”语句或者“?”运算符,在绘制矩形的高度小于两倍行高时才传递“NoWrap”标记。 - Michael Liu

4

作为解决方法,您可以给DrawString方法一个比您实际想要的RectangleF更大的矩形,并将您的Graphics对象的剪辑区域设置为您想要绘制字符串的实际RectangleF

RectangleF rect = new RectangleF(10, 10, 30, 15);
e.Graphics.DrawRectangle(Pens.Red, Rectangle.Truncate(rect));

RectangleF fakeRect = new RectangleF(rect.Location, new SizeF(short.MaxValue, short.MaxValue));

Region r = e.Graphics.Clip;
e.Graphics.SetClip(rect);            
e.Graphics.DrawString("1 Default", this.Font, SystemBrushes.ControlText, fakeRect);
e.Graphics.Clip = r;

请注意,此代码假定您希望将文本锚定到矩形的左上角。否则,您应该生成一个虚拟矩形,以保持与您预期的布局矩形相同的锚点。


这可能是最好的方法。DrawString() 的修剪选项是在显示之前操作字符串。然而,您想要的是全部显示并裁剪。 - DonBoitnott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接