我希望有人可以帮我解决我使用Compact Framework.Net 2 SP 2时遇到的问题。
目前我有一个带有一系列文本框的UI,每个文本框都显示数据库字段的内容。这些显示在另一个下面,在表单的右侧有一个滚动条。每个文本框的设置宽度可能
我想根据每个文本框的行数,字体大小和字体调整每个文本框的高度,以避免在每个文本框上使用滚动条。
目前,我已经能够在测试应用程序中执行此操作。
see screenshot for output http://morrislgn.brinkster.net/SO/screenshot.jpg
'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
最后,我知道这可以通过使用p / invoke调用COREDLL.dll来实现,但这样做会导致应用程序崩溃。
嗨伙计,
以下是所要求的pinvoke代码:
<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
谢谢,
莫里斯
答案 0 :(得分:0)
想想我已经到底了:
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
当然,它有点像黑客但它现在似乎工作正常!关于如何改进这一点的任何意见或评论都非常受欢迎。
另外,关于p / invoke的东西,发现了问题的根源,或者更确切地说是解决方案。在我的设备上升级了.Net fx,这似乎解决了这个问题。
由于
莫里斯
答案 1 :(得分:0)
好吧,我建议给你一个健全而聪明的解决方案。 这是算法:
分配: •文本框到标签的大小。 •Label文本框的字体。 •Label的自动调整属性为 True 。 •标签截至文本框的BorderStyle属性。 •Label的MinimumSize属性作为文本框的原始大小。 •标签的MaximumSize属性为宽度 - 与原始高度相同,高度为原始高度的大倍数。
将文本框的文本分配给标签的文本。
我也在MSDN论坛上发布了类似的解决方案,也可以检出: [http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/03fc8e75-fc13-417a-ad8c-d2b26a3a4dda][1]
的问候。 :)
答案 2 :(得分:0)
我问了一个类似的问题并得到了一个完全满足我对这个问题的需求的答案!请从我的问题中查看stevo3000的答案: AutoSize for Label / TextBox in .NET Compact Framework
他提到了这两篇博文,只用一次刷卡就完全解决了我的问题! http://www.mobilepractices.com/2007/12/multi-line-graphicsmeasurestring.html http://www.mobilepractices.com/2008/01/making-multiline-measurestring-work.html