2011-05-18 35 views
1

當然,Graphics.MeasureString方法是衆所周知的有襯墊的問題,所以你用Graphics.MeasureCharacterRanges代替,但你可以在這裏看到:MeasureCharacterRanges甚至不準確?

MeasureCharacterRanges problem

它不是相當正確的測量。這是MeasureCharacterRanges的問題還是我的代碼?我該如何解決它?

這裏是我的代碼:

'Draw the selection cursor 
    If Me.Focused Then 
     Dim cX As Integer = 1, cY As Integer = 5, c As Char 
     For i As Integer = 0 To Me.SelectionStart - 1 
      c = Me.Text(i) 

      If c = ControlChars.CrLf Then 
       cY += Me.Font.Height 
      Else 
       Dim w As Integer = MeasureCharacter(g, c, Me.Font).Width 
       g.DrawRectangle(Pens.Black, cX, cY, w, Me.Font.Height) 'Draw a rectangle for debugging 
       cX += w 
      End If 
     Next 

     g.DrawLine(Pens.Black, cX, cY, cX, cY + Me.Font.Height) 
    End If 
End Sub 

Protected Function MeasureCharacter(ByVal g As Graphics, ByVal c As Char, ByVal f As Font) As Size 
    Dim cr() As CharacterRange = {New CharacterRange(0, 1)} 
    Dim sfmt As New StringFormat() 
    sfmt.FormatFlags = StringFormatFlags.MeasureTrailingSpaces 
    sfmt.SetMeasurableCharacterRanges(cr) 
    Return g.MeasureCharacterRanges(c.ToString(), f, Me.ClientRectangle, sfmt)(0).GetBounds(g).Size.ToSize() 
End Function 

回答

3

測量indiviual字符長度沒有考慮到的字符組之間進行字距,所以字符的長度之和將不等於長度的字符串。

如果你看看你的示例文本,你可以看到「Sprint」結尾處的「t」和「Textbox」開始處的「T」之間的字距變化,字符會比你靠近會期望給定他們的個人長度。

+0

那麼......我該如何解決它? – Ryan 2011-05-18 03:30:15

+0

取決於你想要做的事情。如果你只需要字符串的長度,那麼你可以在字符串上使用MeasureCharacterRanges,這需要考慮字距。 – fivebob 2011-05-18 03:34:11

+0

不,我需要(或者非常願意)以各種原因衡量每個角色。 – Ryan 2011-05-18 03:38:14