Click here to Skip to main content
15,897,187 members
Articles / Mobile Apps / Windows Phone 7

Presentation Patterns for XAML based Applications

Rate me:
Please Sign up or sign in to vote.
4.99/5 (44 votes)
17 Sep 2013CPOL23 min read 95.8K   1.5K   176  
Design patterns on the presentation layer for WPF, Silverlight and Windows Phone applications.
// -- FILE ------------------------------------------------------------------
// name       : MediaPlayerController.cs
// project    : Itenso Community
// created    : Jani Giannoudis - 2012.05.05
// language   : c#
// environment: .NET 4.0
// copyright  : (c) 2004-2012 by Itenso GmbH, Switzerland
// --------------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
#if SILVERLIGHT
using System.Windows.Media;
#endif
using Itenso.Community.XamlPatterns.Commands.Media;
using Itenso.Community.XamlPatterns.Windows.Input;
using ICommand = System.Windows.Input.ICommand;

namespace Itenso.Community.XamlPatterns.Controls
{

	// ------------------------------------------------------------------------
	public class MediaPlayerController : FrameworkElement, IMediaPlayer, INotifyPropertyChanged, IDisposable
	{

		// ----------------------------------------------------------------------
		public event PropertyChangedEventHandler PropertyChanged;

		// ----------------------------------------------------------------------
		public event EventHandler CanPlayChanged;

		// ----------------------------------------------------------------------
		public event EventHandler CanPauseChanged;

		// ----------------------------------------------------------------------
		public event EventHandler CanResumeChanged;

		// ----------------------------------------------------------------------
		public event EventHandler CanStopChanged;

		// ----------------------------------------------------------------------
		public static readonly DependencyProperty MediaElementProperty = DependencyProperty.RegisterAttached(
			"MediaElement",
			typeof( MediaElement ),
			typeof( MediaPlayerController ),
			new PropertyMetadata( MediaElementPropertyChanged ) );

		// ----------------------------------------------------------------------
		public MediaPlayerController()
		{
			playCommand = commands.Register( new PlayCommand( this ) );
			pauseCommand = commands.Register( new PauseCommand( this ) );
			resumeCommand = commands.Register( new ResumeCommand( this ) );
			stopCommand = commands.Register( new StopCommand( this ) );
		} // MediaPlayerController

		// ----------------------------------------------------------------------
		public MediaElement MediaElement
		{
			get { return (MediaElement)GetValue( MediaElementProperty ); }
			set { SetValue( MediaElementProperty, value ); }
		} // MediaElement

		#region State

		// ----------------------------------------------------------------------
		public bool CanPlay
		{
			get { return canPlay; }
			private set
			{
				if ( value != canPlay )
				{
					canPlay = value;
					NotifyPropertyChanged( "CanPlay" );
					OnCanPlayChanged();
				}
			}
		} // CanPlay

		// ----------------------------------------------------------------------
		public bool CanPause
		{
			get { return canPause; }
			private set
			{
				if ( value != canPause )
				{
					canPause = value;
					NotifyPropertyChanged( "CanPause" );
					OnCanPauseChanged();
				}
			}
		} // CanPause

		// ----------------------------------------------------------------------
		public bool CanResume
		{
			get { return canResume; }
			private set
			{
				if ( value != canResume )
				{
					canResume = value;
					NotifyPropertyChanged( "CanResume" );
					OnCanResumeChanged();
				}
			}
		} // CanResume

		// ----------------------------------------------------------------------
		public bool CanStop
		{
			get { return canStop; }
			private set
			{
				if ( value != canStop )
				{
					canStop = value;
					NotifyPropertyChanged( "CanStop" );
					OnCanStopChanged();
				}
			}
		} // CanStop

		// ----------------------------------------------------------------------
		public PlayState PlayState { get; set; }

		// ----------------------------------------------------------------------
		public PlayPositionType PlayPositionType
		{
			get
			{
				MediaElement mediaElement = MediaElement;
				if ( mediaElement == null )
				{
					throw new InvalidOperationException();
				}

				if ( mediaElement.Position == TimeSpan.Zero )
				{
					return PlayPositionType.Begin;
				}
				return mediaElement.Position == mediaElement.NaturalDuration ? PlayPositionType.End : PlayPositionType.Between;
			}
		} // PlayPositionType

		#endregion

		#region Commands

		// ----------------------------------------------------------------------
		public ICommand PlayCommand
		{
			get { return playCommand; }
		} // PlayCommand

		// ----------------------------------------------------------------------
		public ICommand PauseCommand
		{
			get { return pauseCommand; }
		} // PauseCommand

		// ----------------------------------------------------------------------
		public ICommand ResumeCommand
		{
			get { return resumeCommand; }
		} // ResumeCommand

		// ----------------------------------------------------------------------
		public ICommand StopCommand
		{
			get { return stopCommand; }
		} // StopCommand

		#endregion

		#region Actions

		// ----------------------------------------------------------------------
		public void Play( Action onFinished )
		{
			if ( !CanPlay )
			{
				return;
			}
			MediaElement.Position = TimeSpan.Zero;
			MediaElement.Play();
			onFinished();

			PlayState = PlayState.Playing;
			UpdateState();
		} // Play

		// ----------------------------------------------------------------------
		public void Pause( Action onFinished )
		{
			if ( !CanPause )
			{
				return;
			}
			MediaElement.Pause();
			onFinished();

			PlayState = PlayState.Paused;
			UpdateState();
		} // Pause

		// ----------------------------------------------------------------------
		public void Resume( Action onFinished )
		{
			if ( !CanResume )
			{
				return;
			}
			MediaElement.Play();
			onFinished();

			PlayState = PlayState.Playing;
			UpdateState();
		} // Resume

		// ----------------------------------------------------------------------
		public void Stop( Action onFinished )
		{
			if ( !CanStop )
			{
				return;
			}
			MediaElement.Stop();
			MediaElement.Position = TimeSpan.Zero;
			onFinished();

			PlayState = PlayState.Stopped;
			UpdateState();
		} // Stop

		#endregion

		#region Dispose

		// ----------------------------------------------------------------------
		public void Dispose()
		{
			Dispose( true );
			GC.SuppressFinalize( this );
		} // Dispose

		// ----------------------------------------------------------------------
		protected virtual void Dispose( bool disposing )
		{
			if ( disposing )
			{
				commands.Dispose();
			}
		} // Dispose

		#endregion

		// ----------------------------------------------------------------------
		protected virtual void OnCanPlayChanged()
		{
			EventHandler canPlayChanged = CanPlayChanged;
			if ( canPlayChanged != null )
			{
				canPlayChanged( this, EventArgs.Empty );
			}
		} // OnCanPlayChanged

		// ----------------------------------------------------------------------
		protected virtual void OnCanPauseChanged()
		{
			EventHandler canPauseChanged = CanPauseChanged;
			if ( canPauseChanged != null )
			{
				canPauseChanged( this, EventArgs.Empty );
			}
		} // OnCanPauseChanged

		// ----------------------------------------------------------------------
		protected virtual void OnCanResumeChanged()
		{
			EventHandler canResumeChanged = CanResumeChanged;
			if ( canResumeChanged != null )
			{
				canResumeChanged( this, EventArgs.Empty );
			}
		} // OnCanResumeChanged

		// ----------------------------------------------------------------------
		protected virtual void OnCanStopChanged()
		{
			EventHandler canStopChanged = CanStopChanged;
			if ( canStopChanged != null )
			{
				canStopChanged( this, EventArgs.Empty );
			}
		} // OnCanStopChanged

		// ----------------------------------------------------------------------
		protected void NotifyPropertyChanged( string propertyName )
		{
			PropertyTool.RaisePropertyChanged( this, propertyName, PropertyChanged );
		} // NotifyPropertyChanged

		// ----------------------------------------------------------------------
		protected bool HandleCommandRequest( ICommand command, object parameter = null )
		{
			if ( command == null )
			{
				return false;
			}

			if ( !command.CanExecute( parameter ) )
			{
				return false;
			}

			command.Execute( parameter );
			return true;
		} // HandleCommandRequest

		// ----------------------------------------------------------------------
		private void InitState()
		{
			MediaElement mediaElement = MediaElement;
			if ( mediaElement == null )
			{
				return;
			}

			CanPlay = true;
			CanPause = false;
			CanResume = false;
			CanStop = false;
		} // InitState

		// ----------------------------------------------------------------------
		private void UpdateState()
		{
			MediaElement mediaElement = MediaElement;
			if ( mediaElement == null )
			{
				return;
			}

			PlayPositionType playPositionType = PlayPositionType;
			switch ( PlayState )
			{
				case PlayState.Playing:
					CanPlay = false;
					CanPause = true;
					CanResume = false;
					CanStop = true;
					break;
				case PlayState.Paused:
					CanPlay = playPositionType == PlayPositionType.Begin || playPositionType == PlayPositionType.End;
					CanPause = false;
					CanResume = playPositionType == PlayPositionType.Between;
					CanStop = false;
					break;
				case PlayState.Stopped:
					CanPlay = true;
					CanPause = false;
					CanResume = false;
					CanStop = false;
					break;
				default:
					CanPlay = false;
					CanPause = false;
					CanResume = false;
					CanStop = false;
					break;
			}
		} // UpdateState

#if SILVERLIGHT
		// ----------------------------------------------------------------------
		private void MediaElementCurrentStateChangedHandler( object sender, RoutedEventArgs e )
		{
			MediaElement mediaElement = MediaElement;
			if ( mediaElement == null )
			{
				return;
			}

			switch ( mediaElement.CurrentState )
			{
				case MediaElementState.Playing:
					PlayState = PlayState.Playing;
					break;
				case MediaElementState.Paused:
					PlayState = PlayState.Paused;
					break;
				case MediaElementState.Stopped:
					PlayState = PlayState.Stopped;
					break;
				default:
					PlayState = PlayState.Closed;
					break;
			}

			UpdateState();
		} // MediaElementCurrentStateChangedHandler
#else
		// ----------------------------------------------------------------------
		private void MediaEndedHandler( object sender, RoutedEventArgs e )
		{
			PlayState = PlayState.Paused;
			UpdateState();
		} // MediaEndedHandler
#endif

		// ----------------------------------------------------------------------
		private static void MediaElementPropertyChanged( DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e )
		{
			MediaPlayerController mediaPlayerControl = (MediaPlayerController)dependencyObject;

			if ( e.OldValue != null )
			{
				MediaElement mediaElement = (MediaElement)e.OldValue;
#if SILVERLIGHT
				mediaElement.CurrentStateChanged -= mediaPlayerControl.MediaElementCurrentStateChangedHandler;
#else
				mediaElement.MediaEnded -= mediaPlayerControl.MediaEndedHandler;
#endif
			}

			if ( e.NewValue != null )
			{
				MediaElement mediaElement = (MediaElement)e.NewValue;
#if SILVERLIGHT
				mediaElement.CurrentStateChanged += mediaPlayerControl.MediaElementCurrentStateChangedHandler;
#else
				mediaElement.MediaEnded += mediaPlayerControl.MediaEndedHandler;
#endif
			}

			mediaPlayerControl.InitState();
		} // MediaElementPropertyChanged

		// ----------------------------------------------------------------------
		// members
		private readonly CommandCollection commands = new CommandCollection();
		private readonly ICommand playCommand;
		private readonly ICommand pauseCommand;
		private readonly ICommand resumeCommand;
		private readonly ICommand stopCommand;
		private bool canPlay;
		private bool canPause;
		private bool canResume;
		private bool canStop;

	} // class MediaPlayerController

} // namespace Itenso.Community.XamlPatterns.Controls
// -- EOF -------------------------------------------------------------------

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)
Switzerland Switzerland
👨 Senior .NET Software Engineer

🚀 My Open Source Projects
- Time Period Library 👉 GitHub
- Payroll Engine 👉 GitHub

Feedback and contributions are welcome.



Comments and Discussions