Como posso calcular o número de linhas em uma caixa de texto?
-
09-09-2019 - |
Pergunta
Eu estou esperando que alguém pode me ajudar com um problema que eu tenho no momento usando Compact Framework.Net 2 SP 2.
No momento eu tenho uma interface de usuário com uma série de caixas de texto e cada caixa de texto exibe o conteúdo de um campo de banco de dados. Estes são mostrados um abaixo outro com uma barra de rolagem no lado direito do formulário. Cada caixa de texto tem uma largura conjunto que pode
Eu gostaria de ajustar a altura de cada caixa de texto com base no número de linhas que está segurando, o tamanho da fonte e a fonte, a fim de evitar o uso de barras de rolagem em cada caixa de texto.
No momento eu estou sido capaz de fazer isso em um aplicativo de teste.
Captura de tela:
veja a imagem para a saída http://morrislgn.brinkster.net/SO/screenshot.jpg
Meu código:
'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
Finalmente, eu sei que isso pode ser conseguido usando uma chamada para o Coredll.dll usando p / invoke, mas fazer isso faz com que a falha de aplicativo.
Oi Gente,
Abaixo está o código pinvoke conforme solicitado:
<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
Obrigado,
Morris
Solução
Eu fiz uma pergunta semelhante e tem uma resposta que completamente satisfeito as minhas necessidades sobre o assunto! Por favor, confira a resposta de stevo3000 da minha pergunta: AutoSize para Label / TextBox no .NET Compact Framework
Ele se referiu a estes dois posts que apenas completamente fixo meu problema com um golpe! http://www.mobilepractices.com/2007/12/multi- A linha-graphicsmeasurestring.html http://www.mobilepractices.com/2008/01/ making-multilinha-MeasureString-work.html
Outras dicas
Pense cheguei ao fundo deste:
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
Com certeza, seu pouco um de um hack, mas parece ok trabalho no momento! Quaisquer observações ou comentários sobre como melhorar este são mais do que bem-vindos.
Além disso, sobre a p / invoke coisas, descobriu a raiz do problema, ou melhor, a solução. Atualizou o fx Net no meu dispositivo e que parece ter resolvido o problema.
Graças
Morris
Bem, gostaria de sugerir uma solução inteligente de som e para você. Aqui está o Algoritmo:
- Use um controle Label para referência.
-
Atribuir: • O tamanho da caixa de texto para o Label. • A fonte de caixa de texto para o Label. • Autosize-propriedade do rótulo a ser true . • BorderStyle propriedade da etiqueta a partir de Caixa de texto'. • MinimumSize Propriedade da etiqueta como tamanho original da caixa de texto. • MaximumSize Propriedade da etiqueta como Largura-mesmo que o original e altura para ser uma grande múltipla a altura original.
-
Atribuir texto da caixa de texto' ao texto de Label.
- Agora: se o PrefferdHeight-propriedade da Label> Altura da caixa de texto == true É hora de aumentar a altura da caixa de texto e verificar a condição acima até que seja False.
- A etiqueta pode ser eliminados agora.
Eu também postou uma solução semelhante no MSDN Forum, que também pode ser verificado: [ http : //social.msdn.microsoft.com/Forums/en-US/winforms/thread/03fc8e75-fc13-417a-ad8c-d2b26a3a4dda] [1]
Cumprimentos. :)