Here is some code I wrote as an example for you. It should do exactly what you want. There are tons of optimizations that can be made, but this is the basics.
LT
Code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace DrawAnimation
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
/// <summary>
/// The rectangle that the smaller rectangle follows.
/// </summary>
private Rectangle mRect = new Rectangle(10, 10, 100, 100);
/// <summary>
/// A timer to move the rectangle (causes the animation)
/// </summary>
private System.Threading.Timer mTimer = null;
/// <summary>
/// The point where the rectangle is along the path.
/// </summary>
private Point mPoint;
/// <summary>
/// The width of the moving rectangle.
/// </summary>
private const int RECT_WIDTH = 4;
/// <summary>
/// The height of the moving rectangle.
/// </summary>
private const int RECT_HEIGHT = 4;
/// <summary>
/// Animation rate in milliseconds.
/// </summary>
private const int ANIMATION_RATE = 100;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//You have to do this to remove the flicker
this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
//Initialize the point to start in the top left corner
mPoint = new Point(mRect.Location.X, mRect.Location.X);
//Set up the function to call when the timer fires
TimerCallback timercb = new TimerCallback(TimerCB);
//Set up the timer to fire at the set animation rate
mTimer = new System.Threading.Timer(timercb, null, ANIMATION_RATE, ANIMATION_RATE);
}
/// <summary>
/// Move the point to the next location on the rectangle
/// </summary>
private void MovePoint()
{
//Move along the right side
if (mPoint.X == mRect.Right)
{
//Only do it if we aren't at the bottom of the right edge
if (mPoint.Y != mRect.Bottom)
{
mPoint.Offset(0,1);
return;
}
}
//Move along the bottom side
if (mPoint.Y == mRect.Bottom)
{
//Only do it if we aren't at the left side of the bottom edge
if (mPoint.X != mRect.Left)
{
mPoint.Offset(-1,0);
return;
}
}
//Move along the left side
if (mPoint.X == mRect.Left)
{
//Only do it if we aren't at the top side of the left edge
if (mPoint.Y != mRect.Top)
{
mPoint.Offset(0,-1);
}
}
//Move along the top side
if (mPoint.Y == mRect.Top)
{
//Only do it if we aren't at the right side of the top edge
if (mPoint.X != mRect.Right)
{
mPoint.Offset(1,0);
}
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
/// <summary>
/// Handle painting the form
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
//Get a reference to the graphics object
Graphics g = e.Graphics;
//Fill the background of the client area
g.FillRectangle(SystemBrushes.Control, this.ClientRectangle);
//Draw the big rectangle track
g.DrawRectangle(Pens.Black, mRect);
//Clone the point
Point p = new Point(mPoint.X, mPoint.Y);
//Offset it by half the width and height of the desired rectangle
p.Offset(-(RECT_WIDTH/2), -(RECT_HEIGHT/2));
//Draw the little moving rectangle
g.FillRectangle(Brushes.White, new Rectangle(p, new Size(RECT_WIDTH, RECT_HEIGHT)));
}
/// <summary>
/// This is called when the timer fires.
/// </summary>
/// <param name="o"></param>
protected void TimerCB(object o)
{
//Move the rectangle
MovePoint();
//Redraw the form
Invalidate();
}
}
}