使用MVVM,我有一个包含3个视图模型的窗口。2个呈现数据和一个音频播放器ViewModel。与其中2个用户界面的交互应触发音频设备的“停止命令”,即
PlaybackDevice.Stop();
由于我具有用于“播放”和“停止”的相同按钮,因此可以通过来自同一按钮的同一命令来管理播放/停止事件。但不是任何其他按钮。 我试图实例化Player类,并调用一个包含PlaybackDevice.Stop()的Stop方法;没用,所以我创建了一个静态的PlaybackDevice设备并直接从ViewModels调用它-仍然不起作用。我应该如何实现这一目标?
Player ViewModel:
#region Commands
public ICommand PlayStopTrack { get; set; }
// public ICommand
#endregion
#region Classes
HardwareManager hm = new HardwareManager();
public Mp3FileReader TrackMp3 { get; set; }
public WaveFileReader TrackWav { get; set; }
#endregion
#region Properties
private static string trackToPlay;
public static string TrackToPlay
{
get { return trackToPlay; }
set
{
trackToPlay = value;
}
}
//public string TrackToPLay { get; set; }
public string DidTrackStop{get;set;}
public static WasapiOut PlaybackDevice { get; set; }
public PlayerVM()
{
PlayStopTrack = new RelayCommand(PlayPressed, CanExecute);
}
private bool CanExecute(object obj)
{
return true;
}
//take the default audio device
void GetDevice()
{
Console.WriteLine("Prepare Device");
if (PlaybackDevice == null)
{
PlaybackDevice = hm.InitialiseAudioPlaybackDevice();
}
}
public void PlayTrackFromBeginning(string trackFullPath)
{
if (trackFullPath != null )
{
string fileExtension = Path.GetExtension(trackFullPath);
switch (fileExtension)
{
case ".mp3":
try
{
Console.WriteLine("Init Playing");
TrackMp3 = new Mp3FileReader(trackFullPath);
if (PlaybackDevice == null)
{
GetDevice();
PlaybackDevice.PlaybackStopped += OnPlaybackStopped;
}
if (PlaybackDevice.PlaybackState == PlaybackState.Stopped)
{
PlaybackDevice.Init(TrackMp3);
PlaybackDevice.Play();
GetTrackLength();
}
//}
//catch (Exception e)
//{
// MessageBox.Show(e.Message + " 1- " + e.InnerException);
//}
break;
case ".wav":
//try
//{
Console.WriteLine("Init Playing");
GetDevice();
PlaybackDevice.PlaybackStopped += OnPlaybackStopped;
//TODO implement wav reader.
TrackWav = new WaveFileReader(trackFullPath);
PlaybackDevice.Init(TrackWav);
PlaybackDevice.Play();
GetTrackLength();
//}
//catch (Exception e)
//{
// MessageBox.Show(e.Message + " - " + e.InnerException);
//}
break;
}
ButtonLabel = "Stop";
}
//the actual stop method
private void OnPlaybackStopped(object sender, StoppedEventArgs e)
{
if (TrackMp3 != null)
{
Console.WriteLine("Init StopEvent");
TrackMp3.Dispose();
PlaybackDevice.Dispose();
TrackMp3 = null;
Position = 0;
CurrentTime = "00:00";
isPlaying = false;
}
if (TrackWav != null)
{
TrackWav.Dispose();
PlaybackDevice.Dispose();
TrackWav = null;
Position = 0;
CurrentTime = "00:00";
isPlaying = false;
}
ButtonLabel = "Play";
}
public void PlayPressed(object o)
{
if (Path.GetExtension(TrackToPlay) == ".mp3")
{
if (isPlaying == false
&& TrackMp3 == null
&& TrackToPlay != null)
{
PlayTrackFromBeginning(TrackToPlay);
// IsTrackPlaying = true;
isPlaying = true;
Timer.Start();
}
else if (PlaybackDevice.PlaybackState==PlaybackState.Playing)
{
MessageBox.Show("Stopping ama kur!");
PlaybackDevice.Stop();
isPlaying = false;
//Thread.Sleep(1000);
// PlayTrackFromBeginning(TrackToPLay);
}
}
if (Path.GetExtension(TrackToPlay) == ".wav")
{
if (isPlaying == false
&& TrackWav == null
&& TrackToPlay != null)
{
PlayTrackFromBeginning(TrackToPlay);
// IsTrackPlaying = true;
isPlaying = true;
Timer.Start();
}
else if (isPlaying == true)
{
PlaybackDevice.Stop();
isPlaying = false;
//Thread.Sleep(1000);
// PlayTrackFromBeginning(TrackToPLay);
}
}
}
答案 0 :(得分:0)
我不确定是否正确理解,但我会尽力帮助您。首先,您的PlayPressed方法在哪里?您使用PlayPressed和CanExecute在ctor中实例化了一个RelayCommand,但是我看不到第一种方法的代码?
答案 1 :(得分:0)
我解决了Singleton类的问题。这样,我总是使用最初播放音乐并通过另一个ViewModel的“播放/停止”按钮停止音乐的对象。