ViewModel中的MediaElement.play()

时间:2014-03-24 09:59:19

标签: c# mvvm windows-phone-8 binding mediaelement

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

我正在使用MVVM patern构建WP8应用程序。我在view.xaml上有一个媒体元素,以及在我的viewmodel.cs中控制这个媒体元素的逻辑(例如,播放,停止,暂停和音量)。

如何使用绑定从我的viewmodel在此媒体元素上播放声音。不破坏MvvM的目的和结构。

(PS:我已经看过以下帖子,但我不确定如何实施它?Link to post

3 个答案:

答案 0 :(得分:10)

您可以直接从视图模型

绑定媒体元素 xaml中的

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

private MediaElement _mediaElementObject;

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

OnNavigatedTo覆盖方法上,您可以创建它的新对象&amp;可以注册它的活动。

MediaElementObject=new MediaElement();

这样你就可以从viewmodel本身做所有事情了。

答案 1 :(得分:0)

答案很不错。我向您展示我的详细代码:(使用caliburn.micro,因此不需要绑定名称)

查看

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

可以帮助某人:)

答案 2 :(得分:0)

以上答案在ViewModel中使用了MediaElement。该元素是VM不可知的View端组件。

实现此目的的一种方法是通过暴露该事件的接口在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();
}