C# | How to implement video (MediaElement) in WPF Prism using the MVVM pattern
How to implement video playback (MediaElement.Play()) in WPF Prism using the MVVM pattern.
This explains how to implement video playback (MediaElement.Play()) in WPF Prism using the MVVM pattern.
IMediaService interface
- Introduce an interface called
IMediaService.
public Interface IMediaService
{
void Play();
void Pause();
void Stop();
void Rewind();
void FastForward();
bool IsPlaying();
}
View code-behind
- Implement
IMediaServiceon the view.
public partial class DemoView : UserControl, IMediaService
{
public DemoView()
{
InitializeComponent();
}
void IMediaService.FastForward()
{
this.MediaPlayer.Position += TimeSpan.FromSeconds(10);
}
void IMediaService.Pause()
{
this.MediaPlayer.Pause();
}
void IMediaService.Play()
{
this.MediaPlayer.Play();
}
void IMediaService.Rewind()
{
this.MediaPlayer.Position -= TimeSpan.FromSeconds(10);
}
void IMediaService.Stop()
{
this.MediaPlayer.Stop();
}
bool IMediaService.IsPlaying()
{
// ローディング完了時はtrue
return this.MediaPlayer.Position < this.MediaPlayer.NaturalDuration;
}
}
View Xaml
- Next, add some code to
DemoView.XAML.
-
Name the
MediaElementso the code-behind can access it as shown above.
<MediaElement Source="{Binding CurrentMedia}" x:Name="MediaPlayer"/> -
Name the view itself so it can be passed as a parameter.
-
Import the interactivity namespace (other required namespaces are omitted).
<UserControl x:Class="Test.DemoView"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
x:Name="MediaService">
- Wire up the
Loadedevent through a trigger, and pass the view itself (x:Name=MediaService) to the view model through a command.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding MediaServiceLoaded}" CommandParameter="{Binding ElementName=MediaService}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
- Prepare buttons (commands) to operate the
MediaElement.
<Button Command="{Binding MoviePlayButton}" Content="Play"></Button>
<Button Command="{Binding MovieStopButton}" Content="Stop"></Button>
ViewModel
- Make it possible to call the
MediaElement's methods from the ViewModel.
public class DemoViewModel : BindableBase
{
public DemoViewModel()
{
MediaServiceLoaded = new DelegateCommand<IMediaService>(MediaServiceLoadedExecute);
MoviePlayButton = new DelegateCommand(MoviePlayButtonExecute);
// ...
}
public IMediaService MediaService {get; private set;}
public DelegateCommand<IMediaService> MediaServiceLoaded { get; }
private void MediaServiceLoadedExecute(IMediaService mediaService)
{
this.MediaService = mediaService;
}
public DelegateCommand MoviePlayButton { get; }
private void MoviePlayButtonExecute()
{
if (MediaService == null)
{
return;
}
MediaService.Play();
}
// ...
}
By following these steps, you can play and stop the MediaElement from within the ViewModel.
It requires a bit of code in the code-behind, but I think the resulting code still respects the MVVM pattern.
Related plants
More Tech articles →C# | How to call a MainWindow method from a partial View in WPF Prism
In WPF Prism, you can call a method on the Main Window from a partial view. Using Prism's Event Aggregator avoids direct references between view models and makes it easy to handle events raised within the application.
#csharp#wpf#prismC# | How to call a View method in ContentRegion from MainWindow in WPF Prism
In WPF Prism, an application may consist of a main window and a set of regions contained within it, hosting views and view models that communicate with each other. This explains how to call a method on a view or view model in the Content Region from the Main Window.
#csharp#wpf#prismC# | How to place a Region (ContentControl) inside a dialog screen in WPF Prism
How to display another View in a ContentControl inside a Dialog screen in WPF Prism.
#csharp#wpf#prism