In the good old days of line printers and 80x24 consoles, generating line-by-line text displays was easy. One just opened stdout, /dev/lp, LPT1:, /dev/console, or CON: and started writing characters. The device took care of everything. With graphical windowing systems, it is not as easy. A programmer must use graphics commands to draw text strings at specific window/screen locations, or use widgets designed for that purpose. Even when widgets are available for onscreen display, the programmer must still resort to low-level graphics commands to generate hardcopy output. When writing code to draw text output, some programmers will end up with code like this: // Display user information in two columns void Display''''''User''''''Info(User user, Graphics g, Font font, Rectangle bounds) { Brush brush = System.Drawing.Brushes.Black; int columnOffset = bounds.Left + (bounds.Width / 2); g.Draw''''''String("User Name:", font, brush, origin); g.Draw''''''String(user.Name, font, brush, origin.X + columnOffset, origin.Y); g.Draw''''''String("Full Name:", font, brush, origin.X, origin.Y + font.Height); g.Draw''''''String(user.Full''''''Name, font, brush, origin.X + columnOffset, origin.Y + font.Height); g.Draw''''''String("E-mail:", font, brush, origin.X, origin.Y + 2 * font.Height); g.Draw''''''String(user.Email''''''Address, font, brush, origin.X + columnOffset, origin.Y + 2 * font.Height); g.Draw''''''String("Phone:", font, brush, origin.X, origin.Y + 3 * font.Height); g.Draw''''''String(user.Phone''''''Number, font, brush, origin.X + columnOffset, origin.Y + 3 * font.Height); } Such code is difficult to read and hard to maintain. A useful technique is to define a line-printer-like class that keeps track of the current position within a boundary rectangle and which provides a Write''''''Line() method that makes it easy to generate line-by-line output. Here is a simple example: public class Line''''''Display { private Graphics graphics; private Rectangle bounds; private Brush brush; private Font font; private PointF position; public Line''''''Display(Graphics graphics, Font font, Rectangle bounds) { this.graphics = graphics; this.bounds = bounds; this.brush = System.Drawing.Brushes.Black; this.font = font; this.position = new PointF(bounds.Left, bounds.Top); } public void Write''''''Line(string text) { this.graphics.Draw''''''String(text, this.font, this.brush, this.position); this.New''''''Line(); } public void New''''''Line() { this.position.X = this.bounds.Left; this.position.Y += this.font.Height; } } With such a class, one can write code like this: void Display''''''User''''''Info(User user, Graphics g, Font font, Bounds bounds) { Line''''''Display firstColumn = new Line''''''Display(g, font, bounds); firstColumn.Write''''''Line("User Name:"); firstColumn.Write''''''Line("Full Name:"); firstColumn.Write''''''Line("E-mail:"); firstColumn.Write''''''Line("Phone:"); int columnWidth = bounds.Width / 2; int columnOffset = bounds.Left + columnWidth; Rectangle secondColumnbounds = new Rectangle(bounds.Left + columnOffset, bounds.Top, columnWidth, bounds.Height); Line''''''Display secondColumn = new Line''''''Display(g, font, secondColumnbounds); secondColumn .Write''''''Line(user.User''''''Name); secondColumn .Write''''''Line(user.Full''''''Name); secondColumn .Write''''''Line(user.Email''''''Address); secondColumn .Write''''''Line(user.Phone''''''Number); } This is easier to understand than the original example. If you do a lot of two-column printing, you might want to add something like this to your class: public class Line''''''Display { // ... public void Write''''''At''''''Column(int x, string text) { this.graphics.Draw''''''String(text, this.font, this.brush, x, this.position.Y); } public void Write''''''Two''''''Column''''''Line(string leftText, string rightText) { this.Write''''''At''''''Column(this.bounds.Left, leftText); this.Write''''''At''''''Column(this.bounds.Left + (this.bounds.Width / 2), rightText); this.New''''''Line(); } } And then the example becomes: void Display''''''User''''''Info(User user, Graphics g, Font font, Bounds bounds) { Line''''''Display display = new Line''''''Display(g, font, bounds); display.Write''''''Two''''''Column''''''Line("User Name:", user.User''''''Name); display.Write''''''Two''''''Column''''''Line("Full Name:", user.Full''''''Name); display.Write''''''Two''''''Column''''''Line("E-mail:", user.Email''''''Address); display.Write''''''Two''''''Column''''''Line("Phone:", user.Phone''''''Number); } This basic idea can be extended to support word wrapping and other advanced formatting features. For example, you could add a Write() method that updates the horizontal position as text is added to a line: public class Line''''''Display { // ... public void Write(string text) { SizeF textDisplaySize = this.graphics.Measure''''''String(text, this.font); this.graphics.Draw''''''String(text, this.font, this.brush, this.position); this.position.X += textDisplaySize.Width; } } and then add functionality to take care of automatically calling New''''''Line() before drawing past the right side of the boundary rectangle. When using a class such as this to generate hardcopy output, it is useful to add features for determining page breaks and for adding header and footer text and page numbers to each page.