Search code examples
wpfcaliburn.micromediaelement

Bind button Mediaelement


I have a video that I want to connect Play/Paus/Stop buttons to. My code in my view is like this:

 <MediaElement Source="{Binding MediaUri}" LoadedBehavior="Manual" Visibility="{Binding IsIndexVisible, Converter={StaticResource InvertBoolToHiddenConverter}}" RenderTransformOrigin="0.5,0.877" Margin="0,0,0,19" />
    <Button x:Name="Play" Height="20" Width="40" Visibility="{Binding IsIndexVisible, Converter={StaticResource InvertBoolToHiddenConverter}}"/>

My button should play video when clicked, but nothing happends.

In my viewmodel I have this code to the Playbutton and when I clicked on the button I come here in debug mode but nothing happends.

 public class MoviePlayerViewModel : TreeViewBase<MoviesViewModel>
{


public MoviePlayerViewModel(IDispatcherWrapper dispatcher, IViewManager viewManager, IKeyboardSimulator keyboardSimulator, IToggleInputManager toggleInputManager)
            : base(dispatcher, viewManager, keyboardSimulator, toggleInputManager)
        {
          UpdateGuards();

            ReadMediaFile();

            // Show course viewer at start
            IsIndexVisible = true;
        }

    public void Play(object sender, NavigationEventArgs e)
    {
        MediaElement mediaElement = new MediaElement();
        mediaElement.Source = MediaUri;
        mediaElement.LoadedBehavior = MediaState.Manual;
        mediaElement.Play();
    }

        private Uri _mediaUri;
    public Uri MediaUri
    {
        get
        {
            return _mediaUri;
        }
        set
        {
            _mediaUri = value;
            NotifyOfPropertyChange(() => MediaUri);
            NotifyOfPropertyChange(() => IsIndexVisible);
        }
    }

When I click on the button now I get to the Play method but nothing happends.

I´m using C# WPF and Caliburn micro.


Solution

  • You MediaElement definition in XAML has a binding to MediaUri. So, it would play as soon as MediaUri is assigned. To work around it, you need to LoadedBehavior to your XAML.

    LoadedBehavior="Manual"
    

    Complete Code.

    <MediaElement Source="{Binding MediaUri}" Visibility="{Binding IsIndexVisible, Converter={StaticResource InvertBoolToHiddenConverter}}" RenderTransformOrigin="0.5,0.877" Margin="0,0,0,19" LoadedBehavior="Manual" />
    

    To play the File using MediaElement with MVVM (and in your case Caliburn Micro), would require some more work.

    In ViewModel

    You need to declare a OnPlay event, and Invoke it in your Play Method.

    public event EventHandler OnPlay;
    
    public void Play()
    {
        if(OnPlay!=null)
           this.OnPlay(this, EventArgs.Empty);
    }
    

    In View,

    Add a Loaded Event for your View

    Loaded="Window_Loaded" 
    

    In Code Behind File,

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
    
     var viewModelInstance = DataContext;
     (viewModelInstance as MainWindowViewModel).OnPlay += (s, ev) => {    this.MediaPlayer.Play(); };
    }
    

    Where MediaPlayer is the x:Name of your MediaElement.

    Since the MediaElement doesn't allow us to Play the file from ViewModel, we create a work around with a hack in View. You create a Event in View, which is triggered on the Play method assigned to your Button. The View, in turn, plays the media file.