Website of Markus Griesser


Drawing with GDI+



In this article I will show you how to draw flicker free using GDI+ functionality. What I want to do is using a Label-Control which is resizable and filled using a linear gradient brush. On top of the brush a line and a circle are drawn, repositioned by a timer function.
So, how to start?
At first create a windows application and place a Label-Control with top/left/right/bottom anchor on the window. In the following code I assume that the Label is named label1. It should look like this now:
First step
Now add three variables which are changed in the timer function:

        private int m_nX = 10;
        private int m_nY = 0;
        private int m_nRadius = 100;
    

Add a timer to the windows form, enable it and add the timer function. In this function I will increment the y-variable and decrement the radius of the circle.

        private void timer1_Tick(object sender, EventArgs e) {
            m_nY += 5;
            if (m_nY > label1.Height)
                m_nY = 0;

            m_nRadius -= 10;
            if (m_nRadius <= 10)
                m_nRadius = 100;

            DrawSomething();
        }
    

As you might have seen, an important function is missing. The DrawSomething is implemented as follows:

        private void DrawSomething() {
            // If the window is minimized, this check prevents us
            // from an exception
            if (label1.Width <= 0 || label1.Height <= 0)
                return;

            // Create a bitmap with the size of the Label
            Bitmap bmp = new Bitmap(label1.Width, label1.Height);
            // Create a graphics object from the above bitmap
            Graphics g = Graphics.FromImage(bmp);

            // The brush which fills the background
            System.Drawing.Drawing2D.LinearGradientBrush newBrush = 
                new System.Drawing.Drawing2D.LinearGradientBrush(
                new Point(0, 0), new Point(label1.Width, label1.Height),
                Color.Black, Color.DarkGoldenrod);
            // Fill the background
            g.FillRectangle(newBrush, new Rectangle(
                0, 0, label1.Width, label1.Height));

            // The pen for drawing the thick line
            Pen newPen = new Pen(Color.Red, 8.0f);
            // Draw the line
            g.DrawLine(newPen,
                new Point(m_nX, m_nY),
                new Point(label1.Width - m_nX, m_nY));

            // The pen for drawing the circle
            Pen newPen2 = new Pen(Color.Blue, 3.0f);
            // Draw the circle
            g.DrawEllipse(newPen2, new Rectangle(
                label1.Width / 2 - m_nRadius, label1.Height / 2 - m_nRadius,
                m_nRadius, m_nRadius));

            // Set the created bitmap to the Label-Control
            // Any control which accepts an image would do
            label1.Image = bmp;
        }
    

Due to the reason we created a resizable Label we have to add a delegate for the resizing event of the Label. It simply calls the DrawSomething function.

        private void label1_Resize(object sender, EventArgs e) {
            DrawSomething();
        }
    

Now the result looks as on this screenshot:
Result