The TextRenderer


The TextRenderer class, located in the System.Windows.Forms namespace, is an alternative to the Graphics class for text rendering. Although Graphics and TextRenderer provide similar levels of text-rendering capabilities, the key difference between the two technologies is the underlying rendering API each one encapsulates; the Graphics class uses GDI+, and TextRenderer wraps GDI directly. Thus, when you need to render text using GDI, you can use TextRenderer to save the effort of writing interop code.

TextRenderer provides two methodsDrawText and MeasureTexteach of which has plenty of overloads that almost parallel their Graphics DrawString and MeasureString counterparts:

namespace System.Windows.Forms {   sealed class TextRenderer {     // Methods     public static void DrawText(IDeviceContext dc, ...);     public static Size MeasureText(IDeviceContext dc, ...}     public static Size MeasureText(string text, ...);   } }


Both DrawText and MeasureText, the equivalents of Graphics.DrawString and Graphics.MeasureString, respectively, wrap GDI invocations outside the graphics scope that is native to your applications via GDI+, whose main element is the surface you're drawing to via the Graphics object.[8] But GDI doesn't know anything about that drawing surface, so you need to pass it a device context handle that's wrapped by an IDeviceContext reference to the surface you want to draw text on. This is why several overloads of both DrawText and MeasureText accept an IDeviceContext. Fortunately, the Graphics class implements IDeviceContext, so you can simply pass it to either method.

[8] Although they are conceptually equivalent, it is highly recommended that you don't mix calls between Graphics and TextRenderer DrawXxx and MeasureXxx methods.

There is another set of MeasureText overloads that don't require an IDeviceContext. However, you should prefer those that do because it allows MeasureText to more accurately determine the size needed to display a chunk of text.

Here's how to determine how much space a chunk of text actually needs:

void TextRendererForm_Paint(object sender, PaintEventArgs e) {    Graphics g = e.Graphics;    Size proposedSize = this.ClientRectangle.Size;    // Calculate rendered text size    Size size = TextRenderer.MeasureText(                  g, "Text To Measure", this.Font, proposedSize); }


As you can see, calling the MeasureText method is quite similar to calling Graphics. MeasureString. In addition to support for passing an IDeviceContext object reference, the other important difference between MeasureText and MeasureString is that the former returns a Size object, and the latter returns SizeF; the entire TextRenderer implementation works with integers only.

To render a string with DrawText is almost the same as using Graphics.DrawString, apart from passing an IDeviceContext reference:

void TextRendererForm_Paint(object sender, PaintEventArgs e) {    Graphics g = e.Graphics; // IDeviceContext    Size proposedSize = this.ClientRectangle.Size;    // Calculate rendered text size    Size size =      TextRenderer.MeasureText(        g, "Text To Measure", this.Font, proposedSize);   // Render text to calculated size   Rectangle rect = new Rectangle(0, 0, size.Width, size.Height);   TextRenderer.DrawText(     g, "Text To Measure", this.Font, rect, Color.Black); }


Figure 6.11 illustrates the result.

Figure 6.11. Measuring and Drawing Text with TextRenderer


Of course, this is pretty plain, particularly from the point of view of formatting. Therein lies another consistency with Graphics: the ability to pass special formatting details to both MeasureText and DrawText.

Formatting with TextRenderer

As with Graphics.DrawString, overloads of both the TextRenderer.MeasureText method and the TextRenderer.DrawText method allow you to pass in a special formatting-oriented argument of type TextFormattingFlags:

namespace System.Windows.Forms {    [Flags]    enum TextFormatFlags {      // Default (Top, Left, and GlyphOverhangPadding)      Default = 0,      // Align text to top      Top = 0,      // Align text to left      Left = 0,      // Use glyph overhang in text line height      GlyphOverhangPadding = 0,      // Align text to horizontal center of the rectangle      HorizontalCenter = 1,      // Align text to right      Right = 2,      // Align text to vertical center of rectangle      VerticalCenter = 4,      // Align text to bottom      Bottom = 8,      // Word wrapping      WordBreak = 16,      // Render all text to a single line      SingleLine = 32,      // "\t" characters in text are turned into tabs      ExpandTabs = 64,      // Don't clip text partially outside layout rect      NoClipping = 256,      // Use external leading in text line height      ExternalLeading = 512,      // Don't show underscores at all      NoPrefix = 2048,      // Calculate text metrics using system font      Internal = 4096,      // Render text as if rendered to a TextBox      TextBoxControl = 8192,      // Trim file path by putting ellipsis in the middle      PathEllipsis = 16384,      // Trim to nearest character and show ellipsis      EndEllipsis = 32768,      // Copy the displayed string to source string      ModifyString = 65536,      // Render text in right-to-left order      RightToLeft = 131072,      // Trim to nearest word and show ellipsis      WordEllipsis = 262144,      // Don't line break wide chars      NoFullWidthCharacterBreak = 524288,      // Hide "&" chars intended as underscores      HidePrefix = 1048576,      // Only draw underscores in place of "&"      PrefixOnly = 2097152,      // Use Graphics object clipping      PreserveGraphicsClipping = 16777216,      // Use Graphics object transformations      PreserveGraphicsTranslateTransform = 33554432,      // Don't pad text      NoPadding = 268435456,      // Pad text left and right edges      LeftAndRightPadding = 536870912, }


Using TextFormatFlags, it's easy to center-align a chunk of text that collapses lines of text on a word-by-word basis, replacing hidden text with ellipsis characters:

void TextRendererForm_Paint(object sender, PaintEventArgs e) {    Graphics g = e.Graphics;    Rectangle rect = this.ClientRectangle;    TextFormatFlags flags = TextFormatFlags.HorizontalCenter|                            TextFormatFlags.VerticalCenter|                            TextFormatFlags.WordEllipsis;    TextRenderer.DrawText(      g, "Text To Measure", this.Font, rect, Color.Black, flags); }


The output of this code is shown in Figure 6.12

Figure 6.12. Measuring and Drawing Centered Text with TextRenderer


In general, you will find a lot of crossover between the two text-rendering technologies, particularly from the formatting perspective. Furthermore, knowledge you gain using one technology will serve you well with the other. However, there are also differences between the two technologies that you need to be aware of.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net