Click here to Skip to main content
15,885,309 members
Articles / Multimedia / GDI+

Animation on Windows Forms

Rate me:
Please Sign up or sign in to vote.
1.04/5 (11 votes)
23 Dec 2008CPOL3 min read 73.1K   3.7K   19   3
Implementing a basic animation on a Windows Form.

Introduction

This article is meant to explain how to add animations to a Windows Form. The first section will briefly explain the process behind by designing a Windows Form. Next will be an example of drawing on a Form using the Graphics class. Finally, the article will conclude with code that can either be compiled on the DOS prompt of the .NET Framework, or built using the separate files that comprise the Visual Studio project.

When working with Windows Forms, the Form object is used to represent any window in your application. This includes the top-most main windows in an SDI (Single-Document Interface), as well as the parent and child windows of an MDI (Multiple Document Interface) application. To create a main window, you must:

  1. Derive a custom class from System.Windows.Forms.Form.
  2. Configure the application's Main method to call Application.Run(), passing an instance of your new Form derived class as an argument:
  3. C#
    using System;
    using System.Windows.Forms;
    public class MainForm : Form // derive custom class
    {
        public MainForm(){}
        // run the application
        public static int Main(string[] args)
        {
            Application.Run(new MainForm());
            return 0;
        }
      }
    }

In the world of Windows Forms, a blank form will often have controls dragged and dropped onto it. A control is an element on the form which has properties that are set. The dragging and dropping of the controls onto the design surface of Visual Studio 2005 to then set their properties cause the IDE to generate code that defines the Form file in one Form.cs file and one Form.Designer.cs file. But, suppose we want to use graphics on a form that we want to draw on a form or a control.

Furthermore, suppose we want to build another window inside of the main window in order to achieve animation. To draw on a control or form, you must first:

  1. Create a Graphics object by calling the System.Windows.Forms.CreateGraphics method.
  2. Create a Pen object.
  3. Call a member of the Graphics class to draw on the control using the Pen. Here is an example:

(File: DrawLine.cs; To compile: c:\Windows\Microsoft.NET\Framework\v2.0.50727>csc.exe /target:winexe DrawLine.cs.)

C#
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class MainForm : System.Windows.Forms.Form
{

    private System.ComponentModel.Container components;

    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }


#region Windows Form Designer generated code

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Resize += new System.EventHandler(this.Form1_Resize);
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }
#endregion

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = this.CreateGraphics();

        // Make a big red pen.
        Pen p= new Pen(Color.Red, 7);

        g.DrawLine(p, 1, 1, 100, 100);
    } 

    private void Form1_Resize(object sender, System.EventArgs e)
    {
    }
}

Animation

If compiled on the DOS prompt of the .NET Framework directory, you will see a line that forms a 60 degree angle. Try to picture a parallel line where the ends are connected to form a square. If the line were to move counterclockwise, it would form a rotation that, if traced, would form a path. In video, the frame rate is the number of single frames per second the human eye sees. While it appears as normal motion, it is actually a set of frames, normally 60, that display per second while there is a horizontal and vertical sync rate. Graphics, however, portray motion by animation. Animation is accomplished by instantiating the System.Windows.Forms.Timer class, which takes care of triggering a regular call to a method by a thread on the window. Note that animation occurs inside of the main window, so another window has to be built, one, in this case, that will rotate.

As stated, the Microsoft Visual Studio 2005 IDE generates code so that the properties of the controls are set to actually define the component as fields, while a control is an element on the form. If you download the example and run the solution file, you should see the animation. Because the .NET Framework 2.0 supports partial classes, we can sort of split two source code files down to form one Form file. The zip file for download contains the entire project in C#. The code below is meant to run on the command-line. The reader should note the program.cs, Form1.cs, and Form1.Desinger.cs files that comprise the project. After examining the source and how it is divided, examine the single source code file presented below:

C#
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

public partial class AnimForm : Form {
    private float angle;
    private Timer timer = new Timer();
    private BufferedGraphics bufferedGraphics;

    public AnimForm() {
        BufferedGraphicsContext context = BufferedGraphicsManager.Current;
        context.MaximumBuffer = new Size( this.Width + 1, this.Height + 1 );
        bufferedGraphics = context.Allocate( this.CreateGraphics(),
        new Rectangle( 0, 0, this.Width, this.Height) );
        timer.Enabled = true;
        timer.Tick += OnTimer;
        timer.Interval = 20; // 50 images per second.
        timer.Start();
    }

    private void OnTimer( object sender, System.EventArgs e ) {
        angle ++;
        if (angle > 359)
            angle = 0;
        Graphics g = bufferedGraphics.Graphics;
        g.Clear( Color.Black );
        Matrix matrix = new Matrix();
        matrix.Rotate( angle, MatrixOrder.Append );
        matrix.Translate( this.ClientSize.Width / 2, 
            this.ClientSize.Height/ 2, MatrixOrder.Append );
        g.Transform = matrix;
        g.FillRectangle( Brushes.Azure, -100, -100, 200, 200 );
        bufferedGraphics.Render( Graphics.FromHwnd( this.Handle ) );
    }

    [System.STAThread]
    public static void Main() {
        Application.Run( new AnimForm() );
    }
}

This example of animation is not meant as a substitute for studying the GDI+ library and the the .NET base classes involved. The code should be self-explanatory. Remember, the coordinates start at the upper left hand corner of a window. Comments and corrections are welcome.

References

  • Practical .NET2 and C#2 by Patrick Smacchia

License

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


Written By
Software Developer Monroe Community
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhy not just use WPF? Pin
sbt124-Dec-08 0:33
sbt124-Dec-08 0:33 
AnswerRe: Why not just use WPF? Pin
Roey C12-Oct-10 3:15
Roey C12-Oct-10 3:15 
Generalthis "article' kind of sucks.. Pin
Seishin#25-Mar-08 22:37
Seishin#25-Mar-08 22:37 

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.