Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The solution i came up with was to write a control which extends the standard RichTextBox control.</p> <p>Use the extended control in the same way you would a regular RichTextBox control with the following enhancements: </p> <ul> <li>Call the ScaleFontToFit() method after resizing or text changes. </li> <li>The Horizontal Alignment field can be used to center align the text.</li> <li>The Font attributes set in the designer will be used for the entire region. It is not possible to mix fonts as they will changed once the ScaleFontToFit method is called. </li> </ul> <p>This control combines several techniques to determine if the text still fits within it's bounds. If the text area is multiline, it detects if scrollbars are visible. I found a clever way to detect whether or not the scrollbars are visible without requiring any winapi calls using a clever technique I found on one of <a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/07/07/some-richtextbox-tricks.aspx" rel="nofollow noreferrer">Patrick Smacchia's posts.</a>. When multiline isn't true, vertical scrollbars never appear so you need to use a different technique which relies on rendering the text using a the Graphics object. The Graphic rendering technique isn't suitable for Multiline boxes because you would have to account for word wrapping.</p> <p>Here are a few snippets which shows how it works (link to source code is provided below). This code could easily be used to extend other controls.</p> <pre><code> /// &lt;summary&gt; /// Sets the font size so the text is as large as possible while still fitting in the text /// area with out any scrollbars. /// &lt;/summary&gt; public void ScaleFontToFit() { int fontSize = 10; const int incrementDelta = 5; // amount to increase font by each loop iter. const int decrementDelta = 1; // amount to decrease to fine tune. this.SuspendLayout(); // First we set the font size to the minimum. We assume at the minimum size no scrollbars will be visible. SetFontSize(MinimumFontSize); // Next, we increment font size until it doesn't fit (or max font size is reached). for (fontSize = MinFontSize; fontSize &lt; MaxFontSize; fontSize += incrementDelta) { SetFontSize(fontSize); if (!DoesTextFit()) { //Console.WriteLine("Text Doesn't fit at fontsize = " + fontSize); break; } } // Finally, we keep decreasing the font size until it fits again. for (; fontSize &gt; MinFontSize &amp;&amp; !DoesTextFit(); fontSize -= decrementDelta) { SetFontSize(fontSize); } this.ResumeLayout(); } #region Private Methods private bool VScrollVisible { get { Rectangle clientRectangle = this.ClientRectangle; Size size = this.Size; return (size.Width - clientRectangle.Width) &gt;= SystemInformation.VerticalScrollBarWidth; } } /** * returns true when the Text no longer fits in the bounds of this control without scrollbars. */ private bool DoesTextFit() { if (VScrollVisible) { //Console.WriteLine("#1 Vscroll is visible"); return false; } // Special logic to handle the single line case... When multiline is false, we cannot rely on scrollbars so alternate methods. if (this.Multiline == false) { Graphics graphics = this.CreateGraphics(); Size stringSize = graphics.MeasureString(this.Text, this.SelectionFont).ToSize(); //Console.WriteLine("String Width/Height: " + stringSize.Width + " " + stringSize.Height + "form... " + this.Width + " " + this.Height); if (stringSize.Width &gt; this.Width) { //Console.WriteLine("#2 Text Width is too big"); return false; } if (stringSize.Height &gt; this.Height) { //Console.WriteLine("#3 Text Height is too big"); return false; } if (this.Lines.Length &gt; 1) { //Console.WriteLine("#4 " + this.Lines[0] + " (2): " + this.Lines[1]); // I believe this condition could be removed. return false; } } return true; } private void SetFontSize(int pFontSize) { SetFontSize((float)pFontSize); } private void SetFontSize(float pFontSize) { this.SelectAll(); this.SelectionFont = new Font(this.SelectionFont.FontFamily, pFontSize, this.SelectionFont.Style); this.SelectionAlignment = HorizontalAlignment; this.Select(0, 0); } #endregion </code></pre> <p>ScaleFontToFit could be optimized to improve performance but I kept it simple so it'd be easy to understand.</p> <p><a href="http://www.blakerobertson.com/code/csharp/AutoScalingRichTextBox" rel="nofollow noreferrer" title="Click here to get the source code and demo application">Download the latest source code here.</a> I am still actively working on the project which I developed this control for so it's likely i'll be adding a few other features and enhancements in the near future. So, check the site for the latest code.</p> <p>My goal is to make this control work on Mac using the Mono framework. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload