Drawing Shapes Using GDI+ by ra00l

Introduction

In order to follow this tutorial step-by-step you will need to have installed Visual Studio .NET and .NET Framework. If you only want to take a look at the application, then you will need only .NET Framework.

Getting to Work

The first thing we need to do is open Visual Studio .NET and create a new Windows Application ( File -> New -> Project -> Visual C# Projects -> Windows Application ). Name the project as you desire and set its location to where you think it’s appropriate. For the first part, we will design the application by adding different controls and in the second part we’ll get down to coding.

Let’s select from the Toolbox a ComboBox control and drop it on our form (if the Toolbox is not visible, select View -> Toolbox or simply press Ctrl
+ Alt + X ).

Set its DropDownStyle property to DropDownList and add the following strings to the Items property of the ComboBox: “Line”, “EmptyEllipse”, “FilledEllipse”, “EmptyRectangle”,”FilledRectangle”.

Next, let’s add a GroupBox control and set its Text to “Border”. Inside it, add two Labels.

Let the Text property of the first to “Color”, and the second’s Text to “Size”. Now add a Button in the GroupBox. Set its FlatStyle property to Flat and its BackColor to Black. Also, erase the Text property, set its Name to btn_border and change its Cursor property
to Hand. From this Button we will choose later the color of the border.

The last thing we will add in the Border GroupBox is a NumericUpDown control. Set its TextAlign property to Center, it’s Value to 2 and it’s Name to n_size.

Now, let’s add another GroupBox and set its Text to “Fill”. Inside it, we will add a Label with the Text property set to “Color” and a Button. Set the Button’s FlatStyle to Flat, its BackColor to LightGray, its Cursor property to Hand, erase the Text and leave it blank. Finally, set its Name property to btn_fill. We will need a control to draw on, so let’s add a Panel control and set it’s BackColor to “WhiteSmoke”.
We are finished with the design.

ere is the application’s interface so far:

Finally, we’ve reached the coding part of the application. Let’s begin by declaring some variables that we will use through the application:

Color fill;
private Color border;
private bool mouse_is_down=false;
private Point start;
private Graphics g;

 

The fill and border colors will be used to store the color of the shape’s border and the filling color of the shape(where is necessary). The bool variable mouse_is_down will hold the state of the mouse (if the mouse is pressed, we will be able to draw the shape. If it isn’t, we won’t draw it).
The start Point variable is used to store the coordinates of the Point where the mouse was pressed. And finally, the Graphics object will be created based on the surface on witch we will draw (in this case, the Panel control).
Let’s go into Design view and double-click the form’s surface. A method called form1_Load will be created by Visual Studio .NET. In this method we will do some application initialization:

 
g = panel1.CreateGraphics();
border = Color.Black;
fill = Color.LightGray;

First, we obtain the graphics object from the Panel. On this object we will do the drawing. Next, we assign some default values to the border and fill Colors. Let’s go back to Design view and double-click the btn_border Button. A method called btn_border_Click wil be created. In this method we will add the following:

 
ColorDialog dl = new ColorDialog();
dl.FullOpen = true;
dl.AnyColor = true;

if (dl.ShowDialog() == DialogResult.OK)
{
btn_border.BackColor = dl.Color;
border = dl.Color;
}

We create an instance of the ColorDialog class; we set some of its properties to have a bigger range of colors. The next thing we do is display it. After the user presses OK, we’ll set the BackColor property of our Button to the color selected by the user. Also, we update the border color.
Something similar needs to be done for the other Button, btn_fill:

 
ColorDialog dl = new ColorDialog();
dl.FullOpen = true;
dl.AnyColor = true;
if (dl.ShowDialog() == DialogResult.OK)
{
btn_fill.BackColor = dl.Color;
fill = dl.Color;
}

Now that we have allowed the user to select custom colors, we should begin drawing. To do this, let’s go to Design view and select the Panel. In the Properties window, click the Events button. Scroll down to the Mouse section and double-click the MouseDown property. You will notice that a method called panel1_MouseDown has been created. Do the same for the MouseMove and MouseUp properties.

Let’s go now to the panel1_MouseDown method. This method occurs when the mouse was pressed on the surface on the Panel. Here, we should add the following:

 
mouse_is_down = true;
start = new Point(e.X, e.Y);

We set the mouse_is_down variable to true, and we get the position of the mouse. Let’s go now to the panel1_MouseUp method. This method occurs when the mouse is no longer pressed. Here we must set the mouse_is_down variable to false.

mouse_is_down = false;

Go to the panel1_MouseMove method. Here, we will do the drawing part.

 
if ( mouse_is_down )
{
g.Clear(panel1.BackColor);

 

All the code in this method will execute only if mouse_is_down variable in set to true. The first step is to clear the graphics object obtained from the Panel. Next, we must draw the shapes according to the selected index of the ComboBox.

           
switch(comboBox1.SelectedIndex)
{
 //line
case 0:
g.DrawLine(new
Pen(border,(int)n_size.Value),start,new Point(e.X,e.Y));
break;

If the selected index of the ComboBox is 0 ( the first option in the list — in our case “Line” ), we draw a line. A Pen object is created based on the color of the border and the value of the NumericUpDown control. The next two parameters of the DrawLine method are the start point and the end point. When the mouse was pressed, we remember the  oordinates of the mouse.
During the move of the mouse, the line is redrawn using the start coordinate and the actual location of the mouse’s cursor.

The next value in the ComboBox represents the EmptyEllipse shape.

//empty
ellipse
case 1:
g.DrawEllipse(new Pen(border,(int)n_size.Value), start.X, start.Y,e.X-start.X,e.Y-start.Y);
break;

Here, the DrawEllipse method accepts as parameters the start point, the height and the width. These values are calculated by subtracting from the current position on the mouse the start value.

For the FilledEllipse shape first we draw the EmptyEllipse and then we use FillEllipse method to draw the fill color. You notice that we created a new SolidBrush object, based on the fill color.

                    
//filled ellipse
case 2:
g.DrawEllipse(new Pen(border,(int)n_size.Value), start.X, start.Y,e.X-start.X,e.Y-start.Y);
g.FillEllipse(new SolidBrush(fill),start.X, start.Y,e.X-start.X,e.Y-start.Y);
break;

The EmptyRectangle shape is drawn exactly like the EmptyEllipse:

                    
//empty rectangle
case 3:
g.DrawRectangle(new Pen(border,(int)n_size.Value), start.X, start.Y,e.X-start.X,e.Y-start.Y);
break;

Finally, the FilledRectangle:

                     
//filled rectangle
case 4:
g.DrawRectangle(new Pen(border,(int)n_size.Value), start.X, start.Y,e.X-start.X,e.Y-start.Y);
g.FillRectangle(new SolidBrush(fill),start.X, start.Y,e.X-start.X,e.Y-start.Y);
break;

When using a switch statement, it is recommended that we treat a default case,
in witch we do nothing.

                 
default:
break;
}
}

Run the application and begin drawing. Here is the application in action:

That’s it for now. Until next time, good luck and happy programming!

Raul POPESCU

Attachments:

Project Files: DrawShapesWithGDI+.zip