如何将CommandParameter与RelayCommand一起使用?

时间:2011-12-06 23:44:22

标签: c# wpf mvvm

我仍在学习MVVM和WPF的绳索,目前我正在尝试使用MVVM创建一个Mediaplayer。经过密集的谷歌搜索后,我决定使用CommanParameter是避免代码落后的最佳方法。我认为代码和XAML看起来很好,但没有魔法 - AKA没有发生任何事情。

是否有任何善良的灵魂谁会介意看看我的代码并给我一些建议?一如既往,我真正重视你的答案。请忽略我在RelayCommands中的复数形式,它已经迟到了:)

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);
        }
    }

}

1 个答案:

答案 0 :(得分:1)

一旦设置了属性VideoToPlay,您的示例代码就可以正常工作。你确定要设置这个吗?您的XAML代码段未包含设置此属性的OpenFileDialogCommand的任何用法:

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