Click here to Skip to main content
15,172,004 members
Articles / Multimedia / GDI+
Posted 8 Sep 2009


45 bookmarked

Destination Flicker Board (GDI+ Made Easy)

Rate me:
Please Sign up or sign in to vote.
4.94/5 (19 votes)
8 Sep 2009CPOL3 min read
Shows how easy it can be to create a WinForms UserControl using only GDI+
Frankfurt International Airport Departure Board


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);

        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));

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).


  • 7th September, 2009: Initial version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Australia Australia
Enjoying life developing mobile device software for Contractors Apps and Ezi App.

I also teach C#, Java and Project Management a couple of evenings a week.

Prior to moving to DCB, I'd been a Windows software developer for nearly 15 years

Comments and Discussions

GeneralMy vote of 2 Pin
dwivediknahal17-Sep-09 17:29
Memberdwivediknahal17-Sep-09 17:29 
QuestionRe: My vote of 2 Pin
RobCroll20-Sep-09 0:33
MemberRobCroll20-Sep-09 0:33 
GeneralSimply Brilliant Pin
Scott G Blood16-Sep-09 1:18
MemberScott G Blood16-Sep-09 1:18 
GeneralRe: Simply Brilliant Pin
RobCroll21-Sep-09 0:58
MemberRobCroll21-Sep-09 0:58 
Generalgreat tutorial on GDI+ Pin
BillWoodruff11-Sep-09 20:25
mveBillWoodruff11-Sep-09 20:25 
GeneralRe: great tutorial on GDI+ Pin
RobCroll11-Sep-09 23:09
MemberRobCroll11-Sep-09 23:09 
GeneralRe: great tutorial on GDI+ Pin
BillWoodruff11-Sep-09 23:35
mveBillWoodruff11-Sep-09 23:35 
GeneralRe: great tutorial on GDI+ (faster painting) Pin
RobCroll11-Sep-09 23:20
MemberRobCroll11-Sep-09 23:20 
GeneralInteresting article. Pin
SalizarMarxx10-Sep-09 11:42
MemberSalizarMarxx10-Sep-09 11:42 
Curious, after looking at the code is there a reason your calling CreateGrphics rather than passing the Graphics object obtained from the PatientEventArgs? Its my understanding that CreateGraphics is rather costly...
GeneralRe: Interesting article. Pin
RobCroll11-Sep-09 15:07
MemberRobCroll11-Sep-09 15:07 
GeneralThat's a new one... Pin
Johnny J.8-Sep-09 12:19
professionalJohnny J.8-Sep-09 12:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.