none
如何自动调整 TextBox的高度,以适应其内容? RRS feed

  • 问题

  • 我在DataRepeater 添加了一个 TextBox,绑定数据库中的某列,数据内容大小不一,想实现类似于本论坛的效果,即在宽度固定的情况下,根据数据内容的不同,自动调整TextBox的高度,该如何实现呢?
    韩立学
    2011年7月13日 1:08

全部回复

  • 谢谢回复!TextBox的高度问题解决了,但其容器DataRepeater 的DataRepeaterItem高度总是固定的,该如何解决呢?
    韩立学
    2011年7月13日 8:14
  • 谢谢回复!TextBox的高度问题解决了,但其容器DataRepeater 的DataRepeaterItem高度总是固定的,该如何解决呢?
    韩立学

    可以贴Code让大家研究吗^_^
    Shadowと愉快なコード達
    2011年7月13日 8:54
  • Private Sub DataRepeater1_DrawItem(sender As Object, e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) Handles DataRepeater1.DrawItem

    Dim tb As TextBox = CType(e.DataRepeaterItem.Controls(0), TextBox)

    Dim g As Graphics = Me.CreateGraphics

    tb.Height = CInt(g.MeasureString(tb.Text, tb.Font).Height())

    e.DataRepeaterItem.Height = tb.Height + 27

    End Sub


    韩立学
    2011年7月13日 9:46
  • Hi:

    大概这样调整

    Dim count As Integer = 0
    
    
    
    
     Private Sub DataRepeater1_DrawItem(sender As System.Object, e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) Handles DataRepeater1.DrawItem
    
     Dim tb As TextBox = CType(e.DataRepeaterItem.Controls(0), TextBox)
     Dim g As Graphics = Me.CreateGraphics
     tb.Height = CInt(g.MeasureString(tb.Text, tb.Font).Height())
     e.DataRepeaterItem.Height = tb.Height + 27
    
     count += tb.Height + 27 '这边您可能要再自己加减数字
    
    End Sub
    
    
    
    
    
    
    
    
     Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    
     DataRepeater1.Height = DataRepeater1.Height + count 
    '这边您可能要再自己加减数字,例如:DataRepeater1.Height =DataRepeater1.Height+count +200
    Me.Height = Me.Height + count '这边您可能要再自己加减数字
    End Sub

    Shadowと愉快なコード達


    2011年7月13日 11:27
  • 谢谢回复!

    我试了一下,窗体及DataRepeater的高度随之增加了,但每个DataRepeaterItem的高度是相同的。

    关键是要让DataRepeaterItem根据TextBox的内容调整高度,内容多,则高;否则,则低,就象这个论坛一样。

    在我的代码中,本来希望 e.DataRepeaterItem.Height = tb.Height + 27 实现这一点,但不知何故,这一行代码并未起作用,而是设计时的固定高度。


    韩立学


    2011年7月13日 23:21

  • 在我的代码中,本来希望 e.DataRepeaterItem.Height = tb.Height + 27 实现这一点,但不知何故,这一行代码并未起作用,而是设计时的固定高度。


    韩立学


    不好意思,误解您的意思,请再试试以下是不是您要的效果:

    'e.DataRepeaterItem.Height = tb.Height + 27
    
     DataRepeater1.ItemTemplate.Height = tb.Height + 27 '换成这个
    

    参考:http://social.msdn.microsoft.com/Forums/en-NZ/vbpowerpacks/thread/c93579f2-8b4c-4002-9ce2-152e2dddd10e


    Shadowと愉快なコード達
    Please correct me if my concept is wrong
    2011年7月14日 1:39
  • 谢谢回复!这同样是改变了所有的DataRepeaterItem高度
    韩立学
    2011年7月14日 2:19
  • DataRepeater 可能无法实现类似于本论坛的效果,那么用什么办法能够实现——每贴占用的空间恰好显示其全部内容呢?

    布局如下;

    作者    发贴时间

    贴子内容


    韩立学
    2011年7月14日 7:41
  • 自己写ADO.net把数据捞到Label显示呢?
    Shadowと愉快なコード達
    Please correct me if my concept is wrong
    2011年7月14日 8:03
  • 谢谢回复!TextBox的高度问题解决了,但其容器DataRepeater 的DataRepeaterItem高度总是固定的,该如何解决呢?
    韩立学

    楼主你可以再看看这个贴子:http://social.msdn.microsoft.com/Forums/zh-CN/vbasiczhchs/thread/40d255bb-cbdd-4163-9b5a-8a571d502a5d
    学无止境
    2011年7月14日 12:05
  • DataRepeater 可能无法实现类似于本论坛的效果,那么用什么办法能够实现——每贴占用的空间恰好显示其全部内容呢?
    布局如下;
    作者    发贴时间
    贴子内容

    韩立学
     
    你可以看到e.DataRepeaterItem是只读的。
    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年7月15日 8:09
    版主
  • 看来此题无解,微软是有点“软”啊!只好以TableLayoutPanel1代替了。
    韩立学
    2011年7月15日 8:15
  • 看来此题无解,微软是有点“软”啊!只好以TableLayoutPanel1代替了。
    韩立学


    我俩问的似乎是一类的问题。你的贴子和我的贴子,版主们都耐心地予以回复了。很感谢他们,虽然没有解决,但也启发了一些思路(这是最重要的,你觉得呢?)

    我不觉得此题无解啊,只是大家还没有想到一个好法子耶。没有做不到的,只有想不到的,耶

    也许孟版主抑或feiyun0112版主能解决此问题。而且,我很感谢坛子里版主们,十分欣赏他们这种乐于助人的品德


    学无止境
    2011年7月15日 12:14
  • 本例中,如果TextBox换成RichTextBox ,更没法自动设置高度了!
    韩立学
    2011年7月16日 9:14
  • http://support.microsoft.com/kb/257849/zh-cn

    上有一篇文章谈到RichTextBox的高度问题,但版本过低,我将其转换到vb2010,其中      OldWndProc = SetWindowLong(fhWnd, GWL_WNDPROC, AddressOf MyWndProc) 提示有错误。我未涉及此种用法,请高手指点该如何纠正。
       

    Option Explicit On
    Module Module1
        Private rResize As REQSIZE
        Private MaskHdr As nmhdr
        Private OldWndProc As Long
        Private Const GWL_WNDPROC = (-4)
        Private Const WM_USER = &H400
        Private Const WM_NOTIFY = &H4E
        Private Const SWP_NOMOVE = &H2
        Private Const SWP_SHOWWINDOW = &H40
        Private Const EM_GETEVENTMASK = (WM_USER + 59)
        Private Const EM_SETEVENTMASK = (WM_USER + 69)
        Private Const ENM_REQUESTRESIZE As Long = &H40000
        Private Const EN_REQUESTRESIZE = &H701

        Public gblWidth As Long     ' <--- Var Holder for Richtext Width
        Public gblHeight As Long    ' <--- Var Holder for Richtext Height
        Public Const EM_REQUESTRESIZE = (WM_USER + 65)
        Public Const VBNullPtr = 0&
        Public RichWnd As Long      ' <--- Var Holder for Richtext Hwnd

        Private Structure nmhdr
            Dim hwndFrom As Long
            Dim idfrom As Long
            Dim code As Long
        End Structure

        Private Structure rect
            Dim Left As Long
            Dim Top As Long
            Dim Right As Long
            Dim Bottom As Long
        End Structure

        Private Structure REQSIZE
            Dim nmhdr As nmhdr
            Dim rect As rect
        End Structure

        Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

        Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

        Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

        Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Object, Source As Object, ByVal Length As Long)

        Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

        ' Call SetWindowLong to instantiate the Window Procedure by passing the
        ' Address of MyWndProc.

        Public Sub NewWindowProc(fhWnd As Long)
            On Error Resume Next
            OldWndProc = SetWindowLong(fhWnd, GWL_WNDPROC, AddressOf MyWndProc)
        End Sub

        ' Once the Hook is in place, All messages will be processed by this
        ' function. Test for a WM_NOTIFY and parse the lParam to search for a
        ' specific value. In this case we are looking for EN_REQUESTRESIZE in the
        ' nmhdr structure. If an EN_REQUESTRESIZE is found then grab the next
        ' structure(REQSIZE) from the lParam.

        Public Function MyWndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
            On Error Resume Next

            Select Case Msg
                Case WM_NOTIFY
                    Call CopyMemory(MaskHdr, lParam, Len(MaskHdr))
                    If MaskHdr.code = EN_REQUESTRESIZE Then
                        Call CopyMemory(rResize, lParam, Len(rResize))
                        If rResize.rect.Bottom < gblHeight Then
                            Call SetWindowPos(RichWnd, VBNullPtr, 0, 0, gblWidth, rResize.rect.Bottom, SWP_SHOWWINDOW Or SWP_NOMOVE)
                        Else
                            Call SetWindowPos(RichWnd, VBNullPtr, 0, 0, gblWidth, gblHeight, SWP_SHOWWINDOW Or SWP_NOMOVE)
                        End If
                        ' By modifying 2 of the above parameters you can create an endless bottom
                        ' Richtext control. This may be desirable if you plan to wrap the control
                        ' and use it on a web page. To test this, comment the 'If' Statement above
                        ' and replace it with the SetWindowPos Function call below.
                        ' The control will now Resize itself to its actual contents.

                        'Call SetWindowPos(RichWnd, VBNullPtr, 0, 0, gblWidth, rResize.rect.Bottom, SWP_SHOWWINDOW Or SWP_NOMOVE)
                    End If

                Case Else ' Handle other messages here.
            End Select

            ' Reset windowproc
            MyWndProc = CallWindowProc(OldWndProc, hwnd, Msg, wParam, lParam)

        End Function

        Public Sub ResetWindProc(hwnd As Long)

            On Error Resume Next

            ' Call SetWindowLong to remove the Windows Hook from app.

            Call SetWindowLong(hwnd, GWL_WNDPROC, OldWndProc)

        End Sub

        Public Sub SetMask(fhWnd As Long)
            On Error Resume Next
            Dim CurrentMask As Long
            Dim NewMask As Long
            ' Set the Event Mask to be called.

            CurrentMask = SendMessage(fhWnd, EM_GETEVENTMASK, 0, 0)
            NewMask = (CurrentMask Or ENM_REQUESTRESIZE)
            Call SendMessage(fhWnd, EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE)
        End Sub

    End Module


    韩立学
    2011年7月17日 23:39