Wie kann ich die Anzahl der Zeilen in einem Textfeld zu berechnen?
-
09-09-2019 - |
Frage
Ich hoffe, dass mir jemand mit einem Problem helfen kann ich im Moment habe mit Compact Framework.Net 2 SP 2.
Im Moment habe ich eine Benutzeroberfläche mit einer Reihe von Textfeldern und jedes Textfeld zeigt den Inhalt eines Datenbankfeldes. Diese sind gezeigt eine unter dem anderen mit einer Bildlaufleiste auf der rechten Seite der Form. Jedes Textfeld hat eine Reihe Breite, die Macht
Ich mag die Höhe jedes Textfeld einzustellen, basierend auf der Anzahl der Zeilen es, die Schriftgröße und die Schriftart, um auf jeder Textbox zu vermeiden, mit Bars blättern hält.
Im Moment bin ich in der Lage dies in einer Testanwendung zu tun.
Screenshot:
siehe Screenshot für die Ausgabe http://morrislgn.brinkster.net/SO/screenshot.jpg
Mein Code:
'Text used in this example:
'TextBox1qwertyuiop lkjhgfdsazxcvbnm1234567890 TextBo
'x1qwer tyuioplkjhgfdsazxcvb nm1234567890
'qwe
'End of exmaple text.
Me.Textbox2.Text = Me.Textbox1.Text
Dim pobjGraphic As Graphics = Me.Textbox2.Parent.CreateGraphics()
Dim pobjSize As SizeF
'Padding values:
Dim piTop As Int32 = 4 'top of text and top of textbox
Dim piBottom As Int32 = 3 'bottom of text and top of textbox
Dim piLines As Int32 = 0
'Based on the font size chosen by the user, create a font to perform the calculation with.
Dim piFontSize As Single = 10
If Me.CheckBox1.Checked.Equals(True) Then
piFontSize = 6
ElseIf Me.CheckBox2.Checked.Equals(True) Then
piFontSize = 8
ElseIf Me.CheckBox3.Checked.Equals(True) Then
piFontSize = 12
Else
piFontSize = 10
End If
Dim pobjFont As New Font("Tahoma", piFontSize, FontStyle.Regular)
'Calculate the height of one line.
pobjSize = pobjGraphic.MeasureString("HELLO WORLD", pobjFont)
'Value of pobjSize returned: {Width = 71.0 Height = 13.0}
'Calculate the number of lines
Dim b As Bitmap
b = New Bitmap(1, 1, Imaging.PixelFormat.Format32bppRgb)
'Calculate the number of lines required to display the text properly based on the lenght of the text the width of the control.
'Length of text to show divide by the width of the textbox
piLines = Graphics.FromImage(b).MeasureString(Me.Textbox2.Text, pobjFont).Width / Me.Textbox2.Width
'Value of piLines returned: 2
If piLines = 0 Then
piLines = 1
End If
'Calculate the size of the text to be displayed using the margins, height of one line and number of lines.
Me.Textbox2.Height = (pobjSize.Height * piLines) + piTop + piBottom
' value produced: 33 = (13 * 2) + 4 + 3
'set font of text box
Me.Textbox2.Font = pobjFont
Schließlich weiß ich, das mit einem Aufruf an die coredll.dll p unter Verwendung erreicht werden kann / aufrufen, sondern tun dies macht die Anwendung zum Absturz bringen.
Hallo Leute,
Im Folgenden finden Sie die pinvoke Code wie gewünscht:
<Runtime.InteropServices.DllImport("coredll.dll")> _
Private Function SendMessage( _
ByVal hwnd As IntPtr, ByVal msg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<Runtime.InteropServices.DllImport("coredll.dll")> _
Private Function GetCapture() As IntPtr
End Function
<Runtime.InteropServices.DllImport("coredll.dll")> _
Private Function ReleaseCapture() As Boolean
End Function
Public Function GetNumberOfLines(ByVal ptxtCountBox As TextBox) As Integer
Try
Dim hnd As IntPtr = New IntPtr
ptxtCountBox.Capture = True
' Capture the textbox handle.
hnd = GetCapture()
ptxtCountBox.Capture = False
' Get the count of the lines in the box.
Dim plCount As Integer = SendMessage(ptxtCountBox.Handle, EM_GETLINECOUNT, 0, 0)
' Count the number of return lines as we minus this from the total lines to take.
plCount = plCount - (CharCount(ptxtCountBox.Text, vbCrLf, False))
plCount += RemoveNonASCIIReturns(ptxtCountBox)
ReleaseCapture()
hnd = Nothing
' Return the line count.
Return plCount
Catch ex As Exception
GenerateError(msCLASS_NAME, "GetNumberOfLines", ex.Message.ToString)
End Try
End Function
Danke,
Morris
Lösung
, fragte ich eine ähnliche Frage und bekam eine Antwort, die völlig zufrieden meine Bedürfnisse zu diesem Thema! Bitte beachten Sie auch stevo3000 Antwort aus meiner Frage: Auto-Size for Label / TextBox in .NET Compact Framework
verwies er auf diesen beiden Blog-Posts, die nur mit einem Schlag mein Problem vollständig behoben haben! http://www.mobilepractices.com/2007/12/multi- Line-graphicsmeasurestring.html http://www.mobilepractices.com/2008/01/ Making-mehrzeilige-MeasureString-work.html
Andere Tipps
Denken Sie ich auf den Grund dafür bekam:
Public Function GetNumberOfLines(ByVal pstext As String, ByVal pobjfont As Font, ByVal pobjDimensions As Size) As Decimal
Dim pslines As String() = Nothing
'Used to measure the string to be placed into the textbox
Dim pobjBitMap As Bitmap = Nothing
Dim pobjSize As SizeF = Nothing
Try
Dim psline As String = String.Empty
Dim pilinecount As Decimal = 0.0
'Spilt the text based on the number of lines breaks.
pslines = pstext.Split(vbCrLf)
For Each psline In pslines
'Create a graphics image which is used to work out the width of the text.
pobjBitMap = New Bitmap(1, 1, Imaging.PixelFormat.Format32bppRgb)
pobjSize = Graphics.FromImage(pobjBitMap).MeasureString(psline, pobjfont)
'If the width of the text is less than 1.0 then add one to the count. This would incidcate a line break.
If pobjSize.Width < 1.0 Then
pilinecount = pilinecount + 1
Else
'Based on the dimensions of the text, work out the number of lines. 0.5 is added to round the value to next whole number.
pilinecount = pilinecount + (Round((pobjSize.Width / pobjDimensions.Width) + 0.5))
End If
Next
'If the line count it less than 1 return one line.
If pilinecount < 1.0 Then
Return 1.0
Else
Return pilinecount
End If
Catch ex As Exception
Return 1.0
Finally
If pslines IsNot Nothing Then
Array.Clear(pslines, 0, pslines.Length - 1)
pslines = Nothing
End If
If pobjBitMap IsNot Nothing Then
pobjBitMap.Dispose()
End If
End Try
End Function
Zugegeben, es ist ein bisschen wie ein Hack, aber es scheint im Moment in Ordnung zu arbeiten! Etwaige Beobachtungen oder Kommentare, wie dies zu verbessern, sind mehr als willkommen.
Auch über die p / aufrufen Sachen, entdeckte die Wurzel des Problems, oder besser gesagt die Lösung. Verbesserte das .Net fx auf meinem Gerät und das scheint das Problem gelöst zu haben.
Danke
Morris
Nun, ich würde eine solide und intelligente Lösung vor. Hier ist der Algorithmus:
- Verwenden Sie ein Label-Steuerelement Referenz.
-
zuordnen: • Die Größe der Textbox auf das Etikett. • Die Schrift von Textbox auf das Etikett. • Autosize-Eigenschaft von Label sein True . • Borderstyle-Eigenschaft der Label-als die Textbox‘. • MinimumSize- Eigentum von Etiketten als Originalgröße der Textbox. • Maximum Eigentum von Etiketten als Breite-gleichen wie original und Höhe ein großes Vielfaches der ursprünglichen Höhe zu sein.
-
Weisen Sie die Textbox‘Text zu Label Text.
- Geben Sie nun: Wenn die PrefferdHeight-Eigenschaft Label> Höhe der Textbox == Wahr Es ist Zeit, um die Höhe der Textbox und überprüfen Sie die obige Bedingung zu erhöhen, bis es falsch ist.
- Das Label kann nun entsorgt werden.
Ich habe auch eine ähnliche Lösung in MSDN Forum gepostet, die auch ausgecheckt werden können: [ http : //social.msdn.microsoft.com/Forums/en-US/winforms/thread/03fc8e75-fc13-417a-ad8c-d2b26a3a4dda] [1]
Viele Grüße. :)