Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Destination Flicker Board (GDI+ Made Easy)

0.00/5 (No votes)
8 Sep 2009 2  
Shows how easy it can be to create a WinForms UserControl using only GDI+
Frankfurt International Airport Departure Board

Introduction

This article will show you how to use the System.Drawing classes (also known as GDI+) to create a .NET UserControl for displaying information similar to the old Arrival/Departure boards at airports. As each row changes, the board will flicker through the alphabet to display the new entry.

This article is not meant to teach you how to become a GDI+ expert. It’s really designed to show that GDI+ isn't as hard as many people think. It's designed to encourage developers to create custom controls when existing controls don't meet the requirement, or when you want to add some gloss to your Winforms UI presentation.

Using the Code

Once you have added the AirportDepartureBoard control to your form, you will find that you can not add or remove rows to the control. So the only way of changing a row’s text is to call the control's UpdateRow method. It is best to update the row with the flicker set to Flicker.No while initializing the form. This will avoid slowing down the load time of the form.

MyDepartureBoard.UpdateRow(0, “Hello World” Flicker.No);

Once initialized, to get the flicker working, set the Flicker parameter to Flicker.Yes when updating a row's text.

MyDepartureBoard.UpdateRow(1, “It’s a beautiful day” Flicker.Yes);

The AirportDepartureBoard control, in the download source code, is an example of how to use the Croll.Windows.Forms.DestinationBoard control which does most of the work. The DestinationBoard control has a number of properties you can set at design or run time. These are BoardBackColor, BoardRowDividerColor and BoardFlickerHingeColor. You will find as you change these properties at design time, the changes will be reflected in the form designer (which is nice). One thing worth noting is that the control only displays whole rows using the BoardBackColor. Any space left at the bottom of the control will be displayed using the control's BackColor property.

Using GDI+ to Create a UserControl

GDI+ sounds a bit scary. It gives the impression that you're going to have to do some low level programming to use GDI+. But that’s not the case because the .NET Framework has abstracted the GDI+ functionality into the System.Drawing namespace making the developer's life a whole lot easier and simpler. The centrepiece of the System.Drawing namespace is the Graphics object. Graphics has a number of methods for drawing. This demonstration will highlight some of the easier methods to use when creating your own UserControls. Below is a code snippet that uses two simple graphics methods, FillRectangle and DrawLine.

private void PaintPanel()
{
    //Get the control's Graphics object used to paint
    Graphics g = this.CreateGraphics();
    // Used to paint the row dividers
    Pen dividerPen = new Pen(this.boardRowDividerColor);
    // Used to paint the hinge in the middle of each row
    Pen hingePen = new Pen(this.boardFlickerHingeColor);

    // Paint the control with the board's BoardBackColor
    g.FillRectangle(new SolidBrush(this.boardBackColor), 0, 0,
        	base.Width, this.rowCount * this.rowHeight);

    // Paint row dividers
    for (int i = 0; i <= this.rowCount; i++)
    {
        g.DrawLine(dividerPen, 0, i * this.rowHeight, 
				base.Width, i * this.rowHeight);
    }

    // Paint flicker hinge lines
    for (int i = 0; i < this.rowCount; i++)
    {
        g.DrawLine(hingePen, 0, i * this.rowHeight + (this.rowHeight / 2) + 1,
    	       	base.Width, i * this.rowHeight + (this.rowHeight / 2) + 1);
    }

    // Paint the text values for each row
    for (int i = 0; i < rows.Count; i++)
    {
        PaintRow(new PaintRowParameters(i, Flicker.No, rows[i]));
    }
}

In the next snippet, you will also notice the use of the DrawRectangle and DrawString methods. All these methods are so well named that no explanation is needed making the System.Drawing namespace relatively intuitive. Just as important is the use of Brushes. In this case, a simple SolidBrush has been used, but there are a variety of brushes that can be used to really bring your new control to life. It should also be noted that a number of objects need disposing, so don't forget to dispose of the objects when you have finished using them.

private void PaintCharacter(char c, int colIndex, int rowIndex)
{
    Graphics g = this.CreateGraphics();
    SolidBrush brush = new SolidBrush(ForeColor); //Used to DrawString
    // Used to paint the hinge in the middle of each character
    Pen pen = new Pen(this.boardFlickerHingeColor);

    try
    {
        int x = (this.colWidth * colIndex);
        int y = (this.rowHeight * rowIndex) + 1;
        Rectangle topHalfRect = new Rectangle(x, y, this.colWidth, 
					(this.rowHeight / 2) - 1);
        Rectangle fullRect = new Rectangle(x, y, this.colWidth, this.rowHeight - 1);

        // Just paint the top half of the character first to give
        // the impression that the flap is flicking over
        g.FillRectangle(new SolidBrush(this.boardBackColor), topHalfRect);
        g.DrawString(c.ToString(), this.Font, brush, topHalfRect);
        g.DrawLine(pen, x, y + (this.rowHeight / 2), x +
        	this.colWidth, y + (this.rowHeight / 2));

        // Now paint the whole character
        g.FillRectangle(new SolidBrush(this.boardBackColor), fullRect);
        g.DrawString(c.ToString(), this.Font, brush, fullRect);
        g.DrawLine(pen, x, y + (this.rowHeight / 2), x +
        	this.colWidth, y + (this.rowHeight / 2));
    }
    finally
    {
        g.Dispose();
        brush.Dispose();
        pen.Dispose();
    }
}

As you can see, no rocket science required, no low level programming. Pretty simple code for what I think is a pretty cool control. Definitely, this has just scratched the surface of what can be done with GDI+ but it shows for most custom controls, all you need is a bit of imagination.

Helpful Tip

When working in the System.Drawing space, or charting for that matter, you come across a lot of x and y parameters. The easy way to remember what’s x and what’s y is as simple as reading this page. First you read across (x) and then you read down (y).

History

  • 7th September, 2009: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here