Click here to Skip to main content
15,881,588 members
Articles / Desktop Programming / WPF

A Guided Tour of WPF – Part 1 (XAML)

Rate me:
Please Sign up or sign in to vote.
4.72/5 (197 votes)
19 Apr 2007CPOL7 min read 866.5K   36.8K   796  
A guided tour of the Windows Presentation Foundation, one feature at a time.
using System;
using System.ComponentModel;
using System.Windows.Threading;

namespace WpfHorseRace
{
	/// <summary>
	/// Represents a horse in a race.
	/// </summary>
	public class RaceHorse : INotifyPropertyChanged
	{
		#region Data

		// Static fields
		readonly static Random random;
		static RaceHorse raceWinner = null;

		// Instance fields
		readonly DispatcherTimer timer = new DispatcherTimer();
		readonly string name;
		int percentComplete;

		#endregion // Data

		#region Constructors

		static RaceHorse()
		{
			RaceHorse.random = new Random( DateTime.Now.Millisecond );
		}

		public RaceHorse( string name )
		{
			this.name = name;
			this.percentComplete = 0;
					
			this.timer.Tick += this.timer_Tick;			
		}

		#endregion // Constructors

		#region Public Properties

		public bool IsFinished
		{
			get { return this.PercentComplete >= 100; }
		}

		public bool IsWinner
		{
			get { return RaceHorse.raceWinner == this; }
		}

		public string Name
		{
			get { return this.name; }
		}

		public int PercentComplete
		{
			get { return this.percentComplete; }
			private set
			{
				if( this.percentComplete == value )
					return;

				if( value < 0 || value > 100 )
					throw new ArgumentOutOfRangeException( "PercentComplete" );

				bool wasFinished = this.IsFinished;

				this.percentComplete = value;

				this.RaisePropertyChanged( "PercentComplete" );

				if( wasFinished != this.IsFinished )
				{		
					if( this.IsFinished && RaceHorse.raceWinner == null )
					{
						RaceHorse.raceWinner = this;
						this.RaisePropertyChanged( "IsWinner" );
					}

					this.RaisePropertyChanged( "IsFinished" );	
				}

				// In case this horse was the previous winner and a new race has begun,
				// notify the world that the IsWinner property has changed on this horse.
				if( wasFinished && value == 0 )
					this.RaisePropertyChanged( "IsWinner" );
			}
		}

		#endregion // Public Properties

		#region Public Methods

		public void StartNewRace()
		{
			// When a race begins, remove a reference to the previous winner.
			if( RaceHorse.raceWinner != null )
				RaceHorse.raceWinner = null;

			// Put the horse back at the start of the track.
			this.PercentComplete = 0;

			// Give the horse a random "speed" to run at.
			this.timer.Interval = TimeSpan.FromMilliseconds( RaceHorse.random.Next( 20, 100 ) );

			// Start the DispatcherTimer, which ticks when the horse should "move."
			if( ! this.timer.IsEnabled )
				this.timer.Start();
		}

		#endregion // Public Methods		

		#region timer_Tick

		void timer_Tick( object sender, EventArgs e )
		{
			if( !this.IsFinished )
				++this.PercentComplete;

			if( this.IsFinished )
				this.timer.Stop();
		}

		#endregion // timer_Tick

		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged;

		private void RaisePropertyChanged( string propertyName )
		{
			if( this.PropertyChanged != null )
				this.PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
		}

		#endregion		
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer (Senior)
United States United States
Josh creates software, for iOS and Windows.

He works at Black Pixel as a Senior Developer.

Read his iOS Programming for .NET Developers[^] book to learn how to write iPhone and iPad apps by leveraging your existing .NET skills.

Use his Master WPF[^] app on your iPhone to sharpen your WPF skills on the go.

Check out his Advanced MVVM[^] book.

Visit his WPF blog[^] or stop by his iOS blog[^].

See his website Josh Smith Digital[^].

Comments and Discussions