2009-10-14 175 views
4

給定像素數(例如:300)和字體(固定類型,固定大小,如Consolas),我怎樣才能確定可以繪製的最大字符數GDI +如何確定固定寬度字體和最大寬度的最大字符數(以像素爲單位)

使用GDI +的文本將不會被寫入標籤或如此,但得出:

public void DrawString(string s, Font font, Brush brush, 
    RectangleF layoutRectangle, StringFormat format); 

但我想畫的,因此之前執行某些文本操作,爲什麼我想弄清楚可以安全輸出的最大字符數。

回答

6

System.Drawing.Graphics方法MeasureString墊字符串寬度與一些額外的像素(我不知道爲什麼),所以測量一個固定的寬度長度的字符,然後將其分割成可用的最大寬度將給出可以適合最大寬度的字符數量的太低估計。

要得到的最多字符數,你必須做一些重複這樣的:

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)用一些額外的像素填充邊界以適應懸垂的字形。有道理,但它可能很煩人。請參閱:

http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx

看起來像一個更好的方式來做到這一點是:

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); 
} 
+0

感謝您的信息,我最終使用的東西非常接近這個,雖然有Consolas字體,「numberOfCharacters」返回,這取決於你使用的字符。例如:「a」將返回50,如果我使用「」,它將返回一個不同的數字。我以爲Consolas是固定字體 - 等寬字體? –

+0

最後,我得到寬度爲不同的字符與等寬字體相等的值,但是,''「 - 空間」給我負值「-3.813766E-7」,這很奇怪。有什麼建議? – Gondil

+0

@Gondil:這是一個不可思議的結果,但是因爲您使用的是等寬字體,所以這很重要嗎?您可以只測量「m」的寬度(例如),並將其用作所有字符(包括空格)的寬度。 – MusiGenesis

0

如果是固定寬度,爲什麼不使用floor(pixelcount/fontwidth)?

+0

只適用於等寬字體。 – devstuff

+0

糟糕,沒有正確閱讀這個問題。對於那個很抱歉。 – devstuff

0

我認爲System.Drawing.Graphics.MeasureString()可以幫到你。您可以將其與MeasureCharacterRanges結合使用,或者測量一個字符的大小,然後將此像素數除以此值。像這樣的東西,你可以玩結果來得到它的工作。我相信這將是工作的解決方案,所以請問是否有什麼不清楚=)

3

還有TextRenderer.MeasureText(),產生不同的結果(這是繪製窗口控件時,什麼用,所以它通常更準確)。

關於它的某處有討論,但目前我找不到它。

編輯:This MSDN Article進一步深入。

+1

http://stackoverflow.com/questions/1087157/accuracy-of-textrenderer-measuretext-results – MusiGenesis

+0

TextRenderer.MeasureText比Graphics.MeasureString慢,但對於大多數目的而言這可能並不重要。 – MusiGenesis

+0

感謝您的信息,也會檢查。我只能將1個答案標記爲正確答案,穆西的答覆就是我最終使用的答案。 –

0

雖然這是一個遲到的回覆,但我遇到了同樣的問題。

我認爲你的問題的答案是在你的問題。您提到的函數DrawString函數具有自動修剪長字符串的功能。看看文檔http://msdn.microsoft.com/en-us/library/19sb1bw6.aspx

該函數將修剪字符串,使其適合佈局矩形。您必須將您作爲參數傳遞的stringformat對象的修剪屬性設置爲非無。

1

我看了幾個網站,並提出瞭解決方案,

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)); 
     } 
    } 
} 

我這樣做改變了DevExpress的網格視圖CustomDrawCell事件。 如果您發現此解決方案中存在任何缺陷,請讓我知道。

相關問題