C# 如何确定给定固定宽度字体和最大像素宽度的最大字符数
给定一定数量的像素(比如:300)和字体(固定类型、固定大小,如Console),如何确定使用GDI+绘制的最大字符数 文本不会写入标签等,而是使用GDI+绘制:C# 如何确定给定固定宽度字体和最大像素宽度的最大字符数,c#,.net,gdi+,C#,.net,Gdi+,给定一定数量的像素(比如:300)和字体(固定类型、固定大小,如Console),如何确定使用GDI+绘制的最大字符数 文本不会写入标签等,而是使用GDI+绘制: public void DrawString( string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format ); 但是我想在绘图之前执行某些文本操作,因此我想计算出我可以安全输出的最大字符数。您可以使用它来获得一个gly
public void DrawString( string s, Font font, Brush brush,
RectangleF layoutRectangle, StringFormat format );
但是我想在绘图之前执行某些文本操作,因此我想计算出我可以安全输出的最大字符数。您可以使用它来获得一个glyph的大小。然后检查其中有多少适合您的绘图区域。如果是固定宽度,为什么不直接使用地板(像素计数/fontwidth)?我想可以帮您。您可以将其与MeasureCharacterRanges组合,或者测量一个字符的大小,然后在此值上除以像素数。类似这样的东西,你可以利用结果让它工作。我确信这将是有效的解决方案,因此请询问是否有不清楚的地方=)系统.Drawing.Graphics方法
测量
用几个额外的像素填充字符串宽度(我不知道为什么),因此,测量一个固定长度字符的宽度,然后将其划分为可用的最大宽度,将给出一个太低的估计,即可以容纳最大宽度的字符数
要获得最大字符数,必须执行如下迭代操作:
using (Graphics g = this.CreateGraphics())
{
string s = "";
SizeF size;
int numberOfCharacters = 0;
float maxWidth = 50;
while (true)
{
s += "a";
size = g.MeasureString(s, this.Font);
if (size.Width > maxWidth)
{
break;
}
numberOfCharacters++;
}
// numberOfCharacters will now contain your max string length
}
更新:你每天都能学到新东西。Graphics.MeasureString(和TextRenderer)用几个额外的像素填充边界,以容纳悬垂轮廓。这是有道理的,但也可能令人讨厌。见:
看起来更好的方法是:
using (Graphics g = this.CreateGraphics())
{
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
SizeF size = g.MeasureString("a", this.Font, new PointF(0, 0),
StringFormat.GenericTypographic);
float maxWidth = 50; // or whatever
int numberOfCharacters = (int)(maxWidth / size.Width);
}
还有,这会产生不同的结果(这是在绘制窗口控件时使用的,因此通常更精确)
关于这件事在某处有讨论,但我现在找不到
编辑:更深入一些。虽然这是一个迟到的回复,但我遇到了同样的问题 我想你的问题的答案就在你的问题里面。您提到的函数DrawString函数具有自动修剪长字符串的功能。看看这些文件
该函数将修剪字符串,使其适合布局矩形。您必须将作为参数传递的stringformat对象的修剪属性设置为none以外的值。我阅读了一些网站,并提出了如下解决方案:
using (System.Drawing.Graphics graphics = CreateGraphics())
{
System.Drawing.Size size = TextRenderer.MeasureText(graphics, id, e.Appearance.Font);
if (size.Width > e.Column.Width)
{
int charFit = (int)(((double)e.Column.Width / (double)size.Width) * (double)id.Length);
if (id.Length - charFit + 2 < id.Length)
{
e.DisplayText = string.Format("{0}{1}","...", id.Substring(id.Length - charFit + 2));
}
}
}
使用(System.Drawing.Graphics=CreateGraphics())
{
System.Drawing.Size Size=TextRenderer.MeasureText(图形、id、e.Appearance.Font);
如果(size.Width>e.Column.Width)
{
int charFit=(int)((双精度)e.Column.Width/(双精度)size.Width)*(双精度)id.Length);
if(内径长度-charFit+2<内径长度)
{
e、 DisplayText=string.Format(“{0}{1}”,“..”,id.Substring(id.Length-charFit+2));
}
}
}
我在DevExpress网格视图的CustomDrawCell事件中进行了此更改。
如果您发现此解决方案中存在任何缺陷,请告诉我。TextRenderer.MeasureText比Graphics.MeasureString慢,尽管这对大多数目的可能并不重要。谢谢您提供的信息,我也会检查一下。我只能将1个答案标记为正确答案,Musi的回答就是我最终使用的答案。感谢您提供的信息,我最终使用了与此非常接近的答案,尽管使用ConsoleAS字体时,返回的“numberOfCharacters”取决于您使用的字符。如果使用“a”,它将返回50,如果使用“”,它将返回不同的数字。我以为ConsoleAS是固定字体-等距的?最后,我用等距字体得到不同字符的相同宽度值,但是,
“-space
给我负值-3.813766E-7
,这很奇怪。有什么建议吗?@Gondil:这是一个奇怪的结果,但这有关系吗,因为你使用的是单间距字体?您可以测量“m”的宽度(例如),并将其用作所有字符的宽度(包括空格)。@MusiGenesis当然可以,但这只是一种情况,如果我得到的是文本而不是单间距字体,该怎么办。但我已经计算出了这里的空间。问题仍然在于我得到的标签非常接近于零。