resize a richtextbox

How do I resize a RichTextBox control to be as high as its content There appears to be no way to do this.

I've seen several "solutions" which all basically revolve around this code:


RichTextBox1.Height = RichTextBox1.Font.GetHeight * RichTextBox1.Lines.Length


 



that is; count the number of lines and times it by the height of the font.

Unfortunately, this counts the height of the first font on the rich text control that it encounters, which does NOT solve the problem. Rich Text can contain multiple fonts, multiple font-heights and even embedded graphics (which aren't even counted by the .Lines property!), so the calculation is doomed before it begins. I thought there might be a property which tells you the scrolling height of the control's contents, but can't see such a property. I also thought I could somehow expand the control to an enormous height and then shrink it until a scrollbar would appear, but I don't know how to do that.

I'm completely stuck. Has somebody found a neat solution



Answer this question

resize a richtextbox

  • Todd Biggs MSN

    Hi,

    Try this, using the Find method of the RichTextBox to select each line, and manually computes the Font.Height of each of the line:

    int start = 0;
    int height = 0;

    foreach(string text in richTextBox1.Lines)
    {
     int textloc = richTextBox1.Find(text, start,
      RichTextBoxFinds.WholeWord | RichTextBoxFinds.MatchCase);

      height += richTextBox1.SelectionFont.Height;
      start += text.Length;
    }

    richTextBox1.Height = height;

    Regards,

    -chris



  • Da

    Ravi,

    Can you say the code for Resizing the RichTextBox at run time when paste any text inside the RichTextBox it goes beyound the total height of the RichTextBox.

    with Regards,

    Vimal


  • aceinc

    Thank you,

    You just saved me a lot of time :)



  • markfield88

    This is definately closer. Good idea, but unfortunately it doesn't work. :(

    A RichText can (and in my case, does) contain markup which is richer than plain lines - tables, images, borders and whatnot. As I mentioned, these do not seem counted in the Lines collection, yet they obviously do contribute to the height of the control. Some different types of rich text cause the code to crash - for instance, tables cut and paste into a richtextbox from Word will usually crash it, whereas tables cut and paste from other RTF sources don't. Wierd!

    Another issue here seems to be (although I could be wrong) is that the lines seem to mean "paragraphs". A line may wrap because the control isn't wide enough, but it still only counts lines as "line breaks". This may explain why graphics and tables cause it trouble. My document may only have 5 line breaks but in fact have 10 lines, so this method of calculating the height doesn't work.

  • AparnaG

    I'd pretty much forgotten about it, but fortunately put an archive of it on my blog:

    http://frumbert.org/2005/01/vbnet_richtextbox_editor.html

    Also put the code to get the height of the content of a RichText control on my site too:

    http://frumbert.org/2005/08/vbnet_richtextbox_control_resi.html

    (Both have .zip downloads of the solution code)


  • JuniorDB

    No prob :)

    Keep this thread posted for any solution you may get.
    Thanks as well.

    -chris

  • speertje

    Hi, I found one of your posts here in google cache, but cannot get to the post here anymore...

    It is about richtextbox with toolbar...

    How can I see your example about that

    Thank you

    Duray AKAR

  • Mathematix

    For posterity, CreateGraphics and MeasureString don't work. The example from the help is:



    Private Sub AutoSizeControl(control As Control, textPadding As Integer)
       ' Create a Graphics object for the Control.
       Dim g As Graphics = control.CreateGraphics()
      
       ' Get the Size needed to accommodate the formatted Text.
       Dim preferredSize As Size = g.MeasureString( _
         control.Text, control.Font).ToSize()
      
       ' Pad the text and resize the control.
       control.ClientSize = New Size( _
         preferredSize.Width + textPadding * 2, _
         preferredSize.Height + textPadding * 2)
      
       ' Clean up the Graphics object.
       g.Dispose()
    End Sub

     


    This code measures the length of a string and resizes the control to be that size. This works a treat for controls like buttons a textboxes, but anything with a scrollbar isn't resized properly (try a multi-line text box) because it fails to take into account the space the scrollbars themselves take up. When used with a RichTextBox it often (in my tests) makes it's size (0,0) even if it has content.

    Will trawl codeproject again looking for solutions that use the scrolling height to work it out.

    Thanks for your ideas, Chris.


  • iCe.NET

    Why so much trouble Can't you simply use the ContentsResized event of the RichTextBox



  • DCreedon

    Hi,

    In addition, RichTextBox has a support for Zooming (ZoomFactor property) in which will increase the size of its content base on zoom factor. Thanks for the explanation, I think in your situation, it's best to dig into the RTF format and calculate height from there. I seen other approach (Sorry I lost the code) previously posted in codeproject that they calculate the height of RichTextBox from its vertical scrollbar by hooking into it (I think it is something like increasing the height until there is no longer a vertical scrollbar).

    I'm interrested on solution for this as well, since my upcoming project involves RichTextBox too. I think I'm gonna watch this thread for solution of how to work with your problems as well, since I may encounter the same.


    -chris

  • jlspoels

    I belive I'm much closer to a solution with this - 99% in fact. I'm having some troubles with the code below in gaining the width of the scrollbar, which is a side issue where I sometimes need to know how wide it is (returns 0).

    The form class has RichTextBox1 which contain some rtf (loaded from an embedded resource). It also has a button which resizes the RichTextBox based on the size of its contents. It then turns off the scrollbars, because the scrollbars appear over the inner edge of the object and therefore take up some of its space.

    Though I made this code mostly myself, I found these references helpful in creating this code:

    http://www.dotnet247.com/247reference/msgs/40/203979.aspx

    http://www.vbnet.ru/faq/showtopic.asp id=316

    http://www.codeproject.com/vb/net/VbNetScrolling.asp

    I've split the scrollbar stuff off into a seperate class to make it a bit more reusable. If you can see any mistakes or can solve the scrollbar width/height issue please let me know.


    ' For showing an embedded resource
    Imports System.Reflection
    ' for StructLayout
    Imports System.Runtime.InteropServices
    ' for SizeOf
    Imports System.Runtime.InteropServices.Marshal

    Public Class resize
        Inherits System.Windows.Forms.Form

     ' Windows Form Designer generated code REMOVED

        Private Sub resize_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim Assm As [Assembly] = Me.GetType().Assembly
            Dim RtfStream As System.IO.Stream = Assm.GetManifestResourceStream("MyProject1.Heading2.rtf")
            If Not RtfStream Is Nothing Then
                Me.RichTextBox1.LoadFile(RtfStream, RichTextBoxStreamType.RichText)
                RtfStream.Close()
            End If
        End Sub

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            FitContents(RichTextBox1)
            RichTextBox1.ScrollBars = RichTextBoxScrollBars.None
        End Sub

        Private Sub FitContents(ByVal ctrl As Control)
            If Not ctrl Is Nothing Then
                Dim si As New ScrollingInfo
                Dim h As Integer = si.getScroll(ctrl.Handle, ScrollingInfo.enScrollType.SBS_VERT).nMax
                Dim w As Integer = si.getScroll(ctrl.Handle, ScrollingInfo.enScrollType.SBS_HORZ).nMax
                If w < ctrl.Width Then w = ctrl.Width
                If h < ctrl.Height Then h = ctrl.Height
                ctrl.Size = New Size(w + si.ScrollbarWidth, h + si.ScrollbarHeight)
            End If
        End Sub

    End Class

    Public Class ScrollingInfo
        Const SIF_RANGE = 1
        Const SIF_PAGE = 2
        Const SIF_POS = 4
        Const SIF_DISABLENOSCROLL = 8
        Const SIF_TRACKPOS = 10
        Const SIF_ALL = (SIF_RANGE Or SIF_PAGE Or SIF_POS Or SIF_TRACKPOS)

        Private Declare Function GetSystemMetrics Lib "user32.dll" (ByVal Metric As Integer) As Integer

        Private Declare Function GetScrollInfo Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByRef lpScrollInfo As SCROLLINFO) As Boolean

        <StructLayout(LayoutKind.Sequential)> _
        Public Structure SCROLLINFO
            Public cbSize As Integer
            Public fMask As Integer
            Public nMin As Integer
            Public nMax As Integer
            Public nPage As Integer
            Public nPos As Integer
            Public nTrackPos As Integer
        End Structure

        Enum enScrollType
            SBS_HORZ = 0
            SBS_VERT = 1
        End Enum

        Enum enSysMetric ' /sysinfo/base/getsystemmetrics.htm
            SM_CYHSCROLL = 3
            SM_CXVSCROLL = 20
        End Enum

        ReadOnly Property ScrollbarWidth() As Integer
            Get
                GetSystemMetrics(enSysMetric.SM_CXVSCROLL)
            End Get
        End Property
        ReadOnly Property ScrollbarHeight() As Integer
            Get
                Return GetSystemMetrics(enSysMetric.SM_CYHSCROLL)
            End Get
        End Property

        Public Function getScroll(ByVal hWnd As IntPtr, Optional ByVal ScrollType As enScrollType = enScrollType.SBS_VERT) As SCROLLINFO
            Dim sc As New SCROLLINFO
            sc.fMask = SIF_ALL
            sc.cbSize = SizeOf(sc)
            If GetScrollInfo(hWnd, ScrollType, sc) Then
                Return sc
            End If
        End Function

    End Class


     


  • resize a richtextbox