resize a richtextbox
How do I resize a RichTextBox control to be as high as its content? There appears to beno 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 doesNOT 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?
[1332 byte] By [
frumbert] at [2007-12-17]
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
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.
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
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.
No prob :)
Keep this thread posted for any solution you may get.
Thanks as well.
-chris
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 |
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
Thank you,
You just saved me a lot of time :)
Why so much trouble? Can't you simply use the ContentsResized event of the RichTextBox?
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