MediaElement.play() from within ViewModel

本文关键字:within ViewModel from play MediaElement | 更新日期: 2023-09-27 17:52:46

我正在努力解决以下问题:

我正在使用MVVM模式构建WP8应用程序。我的观点中有一个媒体因素。Xaml和控制我的viewmodel.cs.

中的媒体元素的逻辑(例如,播放,停止,暂停和音量)。

我如何在这个媒体元素上播放声音从我的视图模型使用绑定。不破坏MvvM的目的和结构。

(PS:我看过下面的帖子,但我不确定如何实现它?链接到帖子)

MediaElement.play() from within ViewModel

可以直接从视图模型绑定Media Element

在xaml

:

<ContentControl Content="{Binding MediaElementObject}"/>
在ViewModel

:

private MediaElement _mediaElementObject;
public MediaElement MediaElementObject
{
   get { return _mediaElementObject; }
   set { _mediaElementObject = value;RaisePropertyChanged(); }
}

OnNavigatedTo Override方法中你可以创建它的新对象&可以注册事件。

MediaElementObject=new MediaElement();

所以你可以从视图模型本身做所有的事情。

上面的答案利用了ViewModel中的MediaElement。这个元素是一个视图端组件,VM应该保持不可知。

实现这一点的一种方法是通过暴露该事件的接口在ViewModel中暴露事件,然后通过运行其MediaElement,通过代码隐藏或可能使用交互触发器来让视图响应该事件。

ViewModel:

public interface ISoundPlayer
{
  event Action Play();
}    
public class MyViewModel : ViewModelBase, ISoundPlayer
{
  public event Action Play;
}

视图:

public class MyView : UserControl
{
  ISoundPlayer _SoundPlayer;
  public MyView()
  {
    DataContextChanged += OnDataContextChanged;
    Unloaded += OnUnloaded;
  }  
  void OnDataContextChanged(DependencyObject sender, DataContextChangedEventArgs args)
  {
    if (DataContext is ISoundPlayer player && _SoundPlayer != player)
    {
      if (_SoundPlayer != null)
        _SoundPlayer.Play -= OnPlay;
      _SoundPlayer = player;
      _SoundPlayer.Play += OnPlay;
    }    
  }
  void OnUnloaded(object sender, RoutedEventArgs e)
  {
    if (_SoundPlayer != null)
      _Metronome.Play -= OnPlay;
  }
  void OnPlay() => myMediaElement.Play();
}

湿疹的答案是伟大的。我给你看我的详细代码:(使用caliburn)。所以不需要绑定name)

<<p> 视图/strong>
    <Grid>
         <ContentControl Content="{Binding MediaElementObject}"/>
    </Grid>
    <StackPanel Orientation="Horizontal">
         <Button x:Name="ButtonPlay" Content="Play" Width="220px" Margin="20,5"/>
         <Button x:Name="ButtonStop" Content="Stop" Width="220px" Margin="20,5"/>
         <Button x:Name="ButtonForward" Content="Forward(30s)" Width="220px" Margin="20,5"/>
         <Button x:Name="ButtonBack" Content="Back(30s)"Width="220px" Margin="20,5"/>
     </StackPanel>

ViewModel

    private MediaElement _mediaElementObject = new MediaElement();
    public MediaElement MediaElementObject
    {
        get { return _mediaElementObject; }
        set
        {
            _mediaElementObject = value;
            NotifyOfPropertyChange(() => MediaElementObject);
        }
    }
    public void ButtonPlay()
    {
        MediaElementObject.Source =new Uri( @"C:'Users'admin'Videos'XXXXXX.wmv");
        MediaElementObject.LoadedBehavior = MediaState.Manual;
        MediaElementObject.UnloadedBehavior = MediaState.Manual;
        MediaElementObject.Play();
    }     
    public void ButtonStop()
    {
        MediaElementObject.Stop();
    }
    public void ButtonForward()
    {
        MediaElementObject.Position = _mediaElementObject.Position + TimeSpan.FromSeconds(30);
    }
    public void ButtonBack()
    {
        MediaElementObject.Position = _mediaElementObject.Position - TimeSpan.FromSeconds(30);
    }

May可以帮助别人:)