// MediaButton.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace CustomWPF
{
public enum IconType
{
Play,
Pause
}
public class MediaButton : Control
{
static MediaButton()
{
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
//This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(typeof(MediaButton),
new FrameworkPropertyMetadata(typeof(MediaButton)));
}
#region Fields
RoutedEventHandler _mediaEndedHandler;
#endregion // Fields
#region Dependency Properties
#region Icon Property
///
/// The Dependency Property for the
/// Icon property.
///
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register(
"Icon",
typeof(IconType),
typeof(MediaButton),
new PropertyMetadata(IconType.Play));
///
/// The Outline Icon used for the
/// MediaButton control.
///
public IconType Icon
{
get { return (IconType)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
#endregion // Icon Property
#region MediaPlayer Property
///
/// The Dependency Property for the
/// MediaPlayer property.
///
public static readonly DependencyProperty MediaPlayerProperty =
DependencyProperty.Register(
"MediaPlayer",
typeof(MediaElement),
typeof(MediaButton),
new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(OnMediaPlayerChanged)));
///
/// The ID of the Media Element that the button is tied to.
///
public MediaElement MediaPlayer
{
get { return (MediaElement)GetValue(MediaPlayerProperty); }
set { SetValue(MediaPlayerProperty, value); }
}
///
/// Static Event that is called when the property is changed.
///
/// The object that has changed.
/// The arguments to the property.
private static void OnMediaPlayerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
MediaButton control = (MediaButton)obj;
control.UpdateMediaPlayer(args.OldValue as MediaElement, args.NewValue as MediaElement);
}
#endregion // MediaPlayer Property
#endregion Dependency Properties
#region Events
#region Clicked Event
public static readonly RoutedEvent ClickedEvent =
EventManager.RegisterRoutedEvent("Clicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MediaButton));
public event RoutedEventHandler Clicked
{
add { AddHandler(ClickedEvent, value); }
remove { RemoveHandler(ClickedEvent, value); }
}
void RaiseClickEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(MediaButton.ClickedEvent, this);
RaiseEvent(newEventArgs);
}
protected virtual void OnClick()
{
RaiseClickEvent();
}
#endregion
#endregion
#region Event Handlers
///
/// Event Handler for when the Media Player has ended
/// the media file.
///
/// The Media Player
/// The handler
void Media_MediaEnded(object sender, RoutedEventArgs e)
{
MediaPlayer.Stop();
Icon = IconType.Play;
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
// Determine the right course of action
if (MediaPlayer != null)
{
switch (Icon)
{
case IconType.Play:
{
Icon = IconType.Pause;
MediaPlayer.Play();
break;
}
case IconType.Pause:
{
Icon = IconType.Play;
MediaPlayer.Pause();
break;
}
default:
{
throw new InvalidOperationException("Unexpected IconType detected in MediaButton");
}
}
}
// Raise the event to the users
RaiseClickEvent();
}
#endregion // Event Handlers
#region Methods
///
/// Used to register and unregister from MediaElements that the control are tied to.
///
/// The Media Element (if any) to unregister event notification.
/// The Media ELement on which to register event notification.
void UpdateMediaPlayer(MediaElement oldMedia, MediaElement newMedia)
{
if (newMedia.LoadedBehavior != MediaState.Manual)
{
throw new NotSupportedException("Media Element's LoadedBehavior must be set to Manual to use this MediaButton");
}
// Unregister if necessary
if (_mediaEndedHandler != null &&
oldMedia != null)
{
oldMedia.MediaEnded -= _mediaEndedHandler;
}
// Register for the event
if (newMedia != null)
{
// Create the handler if necessary
if (_mediaEndedHandler == null)
{
_mediaEndedHandler = new RoutedEventHandler(Media_MediaEnded);
}
// Register for the Event
newMedia.MediaEnded += _mediaEndedHandler;
}
}
#endregion // Methods
}
}