RichTextBox size according to content

This code automatically determines the size of the RichTextBox according to its contents. I have problems, especially with tables. \t can be ignored. I tried a managed solution, now I'm trying to call the platform. Current output:

enter image description here

  [DllImport("gdi32.dll")] static extern bool GetTextExtentPoint32(IntPtr hdc, string lpString, int cbString, out SIZE lpSize); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr GetDC(IntPtr hWnd); [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct SIZE { public int cx; public int cy; public SIZE(int cx, int cy) { this.cx = cx; this.cy = cy; } } public static void Main() { Form form = new Form(); RichTextBox rtfBox = new RichTextBox(); rtfBox.Rtf = @"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Arial;}}\viewkind4\uc1\trowd\trgaph100\cellx1000\cellx2000\pard\intbl\lang1033\f0\fs20 hi\cell bye\cell\row\intbl one\cell two\cell\row\pard\par}"; rtfBox.ScrollBars = RichTextBoxScrollBars.None; string sInput = "hi\t bye\t\n";// one\t two\t\n"; SIZE CharSize; form.Controls.Add(rtfBox); IntPtr hdc = GetDC(IntPtr.Zero);//Context for entire screen GetTextExtentPoint32(hdc, sInput, sInput.Length, out CharSize); rtfBox.Width = CharSize.cx; rtfBox.Height = CharSize.cy; form.Visible = false; form.ShowDialog(); } 

(Note: for simplicity, this is a console application with a link to System.Windows.Forms.dll)

+7
source share
3 answers

Did you view the ContentsResized event? Add the following method to call when the event fires:

 private void richTextBox_ContentsResized(object sender, ContentsResizedEventArgs e) { var richTextBox = (RichTextBox) sender; richTextBox.Width = e.NewRectangle.Width; richTextBox.Height = e.NewRectangle.Height; } 

When the contents of an RTF change (using Rtf ), the size of the RichTextBox must be changed to fit its contents. Make sure you also set the WordWrap property to false .


I tried this with your example table and it seems to work (albeit with a slight offset that you could solve by adding a few pixels of width to the adjusted size - I don't know why this is happening):

P.Brian.Mackey EDIT
This answer worked for me. To clarify, here is the latest code, including border correction:

  public static void Main() { string sInput = "hi\t bye\t\n";// one\t two\t\n"; SIZE CharSize; Form form = new Form(); RichTextBox rtfBox = new RichTextBox(); rtfBox.ContentsResized += (object sender, ContentsResizedEventArgs e) => { var richTextBox = (RichTextBox)sender; richTextBox.Width = e.NewRectangle.Width; richTextBox.Height = e.NewRectangle.Height; rtfBox.Width += rtfBox.Margin.Horizontal + SystemInformation.HorizontalResizeBorderThickness; }; rtfBox.WordWrap = false; rtfBox.ScrollBars = RichTextBoxScrollBars.None; rtfBox.Rtf = @"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Arial;}}\viewkind4\uc1\trowd\trgaph100\cellx1000\cellx2000\pard\intbl\lang1033\f0\fs20 hi\cell bye\cell\row\intbl one\cell two\cell\row\pard\par}"; form.Controls.Add(rtfBox); form.ShowDialog(); } 
+12
source

It is much easier to use GetPreferredSize , as described in this answer. Then you don’t have to wait for the ContentResized event,

+2
source

How about the height?
I added

 richTextBox.Height += richTextBox.Margin.Vertical + SystemInformation.VerticalResizeBorderThickness; 

in the end.

It also looks like a good candidate for an extension method:

 static public class RichTextBoxResizer { static public void ResizeToContents(this RichTextBox richTextBox, ContentsResizedEventArgs e) { richTextBox.Width = e.NewRectangle.Width; richTextBox.Height = e.NewRectangle.Height; richTextBox.Width += richTextBox.Margin.Horizontal + SystemInformation.HorizontalResizeBorderThickness + SystemInformation.HorizontalScrollBarThumbWidth; richTextBox.Height += richTextBox.Margin.Vertical + SystemInformation.VerticalResizeBorderThickness; } static public void ResizeToContentsHorizontally(this RichTextBox richTextBox, ContentsResizedEventArgs e) { richTextBox.Width = e.NewRectangle.Width; richTextBox.Width += richTextBox.Margin.Horizontal + SystemInformation.HorizontalResizeBorderThickness + SystemInformation.HorizontalScrollBarThumbWidth; } static public void ResizeToContentsVertically(this RichTextBox richTextBox, ContentsResizedEventArgs e) { richTextBox.Height = e.NewRectangle.Height; richTextBox.Height += richTextBox.Margin.Vertical + SystemInformation.VerticalResizeBorderThickness; } } 

So, the event receiver looks like this:

 private void rtfBox_ContentsResized(object sender, ContentsResizedEventArgs e) { RichTextBox rtb = (RichTextBox)sender; rtb.ResizeToContents(e); } 
0
source

All Articles