I am trying to play small mp3 file in my Windows Phone 7.5 MVVM application (MVVM Light is used).
I am trying:
1st. To use SoundEffect
:
SoundEffectInstance instance;
SoundEffect effect = SoundEffect.FromStream(stream);
instance = effect.CreateInstance();
FrameworkDispatcher.Update();
instance.Play();
Problem: only .wav files allowed.
2nd. To use Microsoft.Xna.Framework.Media.Song:
Microsoft.Xna.Framework.Media.Song song = Microsoft.Xna.Framework.Media.Song.FromUri("name", new Uri("someUri"));
Problem: file is stored in the IsolatedStrorage
and we need to know the full path to the file.
Suggested hint:
string path = stream.GetType().GetField("m_FullPath", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(stream).ToString();
is not working.
3d. To use standard MediaElement
.
Problem: I need an access to the MediaElement
control in the ViewModel
which is not good from the MVVM view.
How to solve this issue?
One way to accomplish this in the MVVM style is to use the MVVM Light Messenger class to send play/pause messages from the viewmodel, which the view would subscribe to and receive.
Say you have a pair of Buttons on your view for Play and Pause. You would drop an EventToCommand behavior on each of them in Expression Blend, and then you would bind them to a pair of RelayCommand properties in your viewmodel, one RelayCommand for Play, one for Pause. For example, in your viewmodel, you would have:
public RelayCommand PlayCommand { get; private set; }
public RelayCommand PauseCommand { get; private set; }
The Play command would have the Messenger send a Play message, and the Pause command would send a Pause message. Each message would be its own simple class:
public class PlayMessage { }
public class PauseMessage { }
Then, in the constructor of your viewmodel, you would create new RelayCommands for the two RelayCommand properties you created earlier that would have actions that have the Messenger send the messages:
MyViewModel()
{
PlayCommand = new RelayCommand( () => SendPlayMessage() );
PauseCommand = new RelayCommand( () => SendPauseMessage() );
}
private void SendPlayMessage()
{
Messenger.Default.Send<PlayMessage>( new PlayMessage() );
}
private void SendPauseMessage()
{
Messenger.Default.Send<PauseMessage>( new PauseMessage() );
}
Your view would then have the Messenger subscribe to both of these message types, and would have actions that would call the Play and Pause methods on the MediaElement:
MyView()
{
Messenger.Default.Register<PlayMessage>
(
this,
( action ) => ReceivePlayMessage( action )
);
Messenger.Default.Register<PauseMessage>
(
this,
( action ) => ReceivePauseMessage( action );
);
}
private void ReceivePlayMessage(PlayMessage msg)
{
myMediaElement.Play();
}
private void ReceivePauseMessage(PauseMessage msg)
{
myMediaElement.Pause();
}
Where myMediaElement is the name you give to the MediaElement in your view's xaml.