Iris Classon
Iris Classon

Reputation: 5842

How to use the CommandParameter with a RelayCommand?

I am still learning the ropes of MVVM and WPF, and at the moment I am trying to create a Mediaplayer using MVVM. After intensive googling I decided that using CommanParameter would be the best way to avoid code behind. I reckon the code and XAML looks fine, but there is no magic- AKA nothing is happening.

Is there any kind soul out there who would mind have a look at my code and give me some advice? As always, I truly value yours answers. Please ignore my plurals in RelayCommands, it was getting late :)

XAML

<MediaElement Name="MediaElement" 
    Source="{Binding VideoToPlay}" 
    Width="400" Height="180" Stretch="Fill"
    LoadedBehavior="Manual" UnloadedBehavior="Manual"/>
<Slider Name="timelineSlider" Margin="5" Width="250" 
    HorizontalAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button 
    Command="{Binding PlayMediaCommand}" 
    CommandParameter="{Binding ElementName=MediaElement, Mode=OneWay}">&lt;&lt;</Button>

C#

class MediaPlayerViewModel: INotifyPropertyChanged
{
    private MediaElement MyMediaElement;

    private Uri _videoToPlay;

    public Uri VideoToPlay
    {
        get { return _videoToPlay; }
        set
        {
            _videoToPlay = value;
            OnPropertyChanged("VideoToPlay");
        }
    }

    void SetMedia()
    {
        OpenFileDialog dlg = new OpenFileDialog();
        dlg.InitialDirectory = "c:\\";
        dlg.Filter = "Media files (*.wmv)|*.wmv|All Files (*.*)|*.*";
        dlg.RestoreDirectory = true;

        if (dlg.ShowDialog() == true)
        {
            VideoToPlay = new Uri(dlg.FileName);

        }
    }

    RelayCommands _openFileDialogCommand;
    public ICommand OpenFileDialogCommand
    {
        get
        {
            if (_openFileDialogCommand == null)
            {
                _openFileDialogCommand = new RelayCommands(p => SetMedia(),
                    p => true);
            }
            return _openFileDialogCommand;
        }
    }

    RelayCommands _playMediaCommand;
    public ICommand PlayMediaCommand
    {
        get
        {
            if (_playMediaCommand == null)
            {
                _playMediaCommand = new RelayCommands(p => PlayMedia(p),
                    p => true);
            }
            return _playMediaCommand;
        }
    }

    void PlayMedia(object param)
    {
        var paramMediaElement = (MediaElement)param;
        MyMediaElement = paramMediaElement;
        MyMediaElement.Source = VideoToPlay;
        MyMediaElement.Play();
    }



    protected void OnPropertyChanged(string propertyname)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyname));
    }

    public event PropertyChangedEventHandler PropertyChanged;




class RelayCommands: ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public event EventHandler CanExecuteChanged;

    public RelayCommands(Action<object> execute)
        : this(execute, null)
    {}

    public RelayCommands(Action<object> execute,
                   Predicate<object> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {

        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }

}

Upvotes: 8

Views: 7299

Answers (1)

RandomActsOfCode
RandomActsOfCode

Reputation: 3285

Your example code works fine once the property VideoToPlay has been set. Are you sure you are setting this? Your XAML snippet did not include any usage of the OpenFileDialogCommand which sets this property:

<Button Content="Select File" Command="{Binding OpenFileDialogCommand}" />

Upvotes: 1

Related Questions