< Day Day Up > |
The Graphics.DrawString method is the most straightforward way to place text on a drawing surface. All of its overloaded forms take a string to be printed, a font to represent the text, and a brush object to paint the text. The location where the text is to be printed is specified by a Point object, x and y coordinates, or a Rectangle object. The most interesting parameter is an optional StringFormat object that provides the formatting attributes for the DrawString method. We'll examine it in detail in the discussion on formatting. Here are the overloads for DrawString. Note that StringFormat is optional in each. Overloads: public DrawString(string, font, brush, PointF [,StringFormat]); public DrawString(string, font, brush, float, float [,StringFormat]); public DrawString(string, font, brush, RectangleF [,StringFormat]); Example: Font regFont = new Font("Tahoma",12); String s = "ice mast high came floating by as green as emerald."; // Draw text beginning at coordinates (20,5) g.DrawString(s, regFont, Brushes.Black, 20,5); regFont.Dispose(); In this example, the upper-left corner of the text string is located at the x,y coordinate 20 pixels from the left edge and 5 pixels from the top of the drawing surface. If the printed text extends beyond the boundary of the drawing surface, the text is truncated. You may want this in some cases, but more often you'll prefer that long lines be broken and printed as multiple lines. Drawing Multi-Line TextSeveral Drawstring overloads receive a rectangle to define where the output string is drawn. Text drawn into these rectangular areas is automatically wrapped to the next line if it reaches beyond the rectangle's boundary. The following code displays the fragment of poetry in an area 200 pixels wide and 50 pixels high. String s = "and ice mast high came floating by as green as emerald." // All units in pixels RectangleF rf = new RectangleF(20,5,200,50); // Fit text in rectangle g.Drawstring(s,regFont,Brushes.Black, rf); Word wrapping is often preferable to line truncation, but raises the problem of determining how many lines of text must be accommodated. If there are more lines of text than can fit into the rectangle, they are truncated. To avoid truncation, you could calculate the height of the required rectangle by taking into account the font (f), total string length(s), and rectangle width (w). It turns out that .NET Graphics.MeasureString method performs this exact operation. One of its overloads takes the string, font, and desired line width as arguments, and returns a SizeF object whose Width and Height properties provide pixel values that define the required rectangle. SizeF sf = g.MeasureString(String s, Font f, int w); Using this method, the preceding code can be rewritten to handle the dynamic creation of the bounding rectangle: Font regFont = new Font("Tahoma",12); String s = "and ice mast high came floating by as green as emerald." int lineWidth = 200; SizeF sf = g.MeasureString(s, regFont, lineWidth); // Create rectangular drawing area based on return // height and width RectangleF rf = new RectangleF(20,5,sf.Width, sf.Height); // Draw text in rectangle g.Drawstring(s,regFont,Brushes.Black, rf); // Draw rectangle around text g.DrawRectangle(Pens.Red,20F,5F,rf.Width, rf.Height); Note that DrawString recognizes newline (\r\n) characters and creates a line break when one is encountered. Formatting Strings with the StringFormat ClassWhen passed as an argument to the DrawString method, a StringFormat object can provide a number of formatting effects. It can be used to define tab positions, set column widths, apply right or left justification, and control text wrapping and truncation. As we will see in the next section, it is the primary tool for creating formatted reports. The members that we will make heaviest use of are shown in Table 9-2.
Using Tab StopsTab stops provide a way to align proportionate-spaced font characters into columns. To set up tab stops, you create a StringFormat object, use its SetTabStops method to define an array of tab positions, and then pass this object to the DrawString method along with the text string containing tab characters (\t). Core Note
As shown in Table 9-2, the SetTabStops method takes two arguments: the offset from the beginning of the line and an array of floating point values that specify the distance between tab stops. Here is an example that demonstrates various ways to define tab stops: float[] tStops = {50f, 100f, 100f}; //Stops at: 50, 150, and 250 float[] tStops = {50f}; // Stops at: 50, 100, 150 You can see that it is not necessary to specify a tab stop for every tab. If a string contains a tab for which there is no corresponding tab stop, the last tab stop in the array is repeated. Listing 9-1 demonstrates using tabs to set column headers. Listing 9-1. Using Tab Stops to Display Columns of Dataprivate void RePaint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Font hdrFont = new Font("Arial", 10,FontStyle.Bold); Font bdyFont = new Font("Arial", 10); // (1) Create StringFormat Object StringFormat strFmt = new StringFormat(); // (2) Define Tab stops float[] ts = {140,60,40}; strFmt.SetTabStops(0, ts); // (3) Define column header text to be printed with tabs string header = "Artist\tCountry\tBorn\tDied"; // (4) Print column headers g.DrawString(header, hdrFont, Brushes.Black,10,10,strFmt); // Print one line below header string artist = "Edouard Manet\tEngland\t1832\t1892"; g.DrawString(artist,bdyFont,Brushes.Black,10, 10 + bdyFont.GetHeight(), strFmt); bdyFont.Dispose(); hdrFont.Dispose(); } Figure 9-3 shows the four-column output from this code. Note that the second column begins at the x coordinate 150, which is the first tab stop (140) plus the x coordinate (10) specified in DrawString. Figure 9-3. Printing with tab stopsThe unit of measurement in this example is a pixel. This unit of measurement is determined by the Graphics.PageUnit property. To override the default (pixels), set the property to a GraphicsUnit enumeration value for example, g.PageUnit = GraphicsUnit.Inch. Be aware that all subsequent drawing done with the Graphics object will use these units. Core Note
String Trimming, Alignment, and WrappingThe StringFormat Trimming and Alignment properties dictate how text is placed within a RectangleF object. Alignment works as you would expect, allowing you to center, right justify, or left justify a string. Trimming specifies how to truncate a string that extends beyond the boundaries of a rectangle when wrapping is not in effect. The basic options are to truncate on a word or character. The following code segments demonstrate some of the common ways these properties can be used to format text strings. Example 1: Printing Without a StringFormat ObjectFont fnt = new Font("Tahoma",10,FontStyle.Bold); RectangleF r = new RectangleF(5,5,220,60); string txt = "dew drops are the gems of morning"; g.DrawString(txt,fnt,Brushes.Black,r); g.DrawRectangle(Pens.Red,r.X,r.Y,r.Width,r.Height); Example 2: Printing with NoWrap Option StringFormat strFmt = new StringFormat(); strFmt.FormatFlags = StringFormatFlags.NoWrap; g.DrawString(txt,fnt,Brushes.Black,r,strFmt); Example 3: Printing with NoWrap and Clipping on a Word StringFormat strFmt = new StringFormat(); strFmt.FormatFlags = StringFormatFlags.NoWrap; strFmt.Trimming = StringTrimming.Word; g.DrawString(txt,fnt,Brushes.Black,r,strFmt); Example 4: Printing with NoWrap, Clipping on Word, and Right Justification StringFormat strFmt = new StringFormat(); strFmt.FormatFlags = StringFormatFlags.NoWrap; strFmt.Trimming = StringTrimming.Word; strFmt.Alignment = StringAlignment.Far; g.DrawString(txt,fnt,Brushes.Black,r,strFmt); StringFormat also has a LineAlignment property that permits a text string to be centered vertically within a rectangle. To demonstrate, let's add two statements to Example 4: strFmt.Alignment = StringAlignment.Center; strFmt.LineAlignment = StringAlignment.Center; |
< Day Day Up > |