I would like to play sounds, and display a progress bar below each sounds I'm displaying the current progress thanks to this in my VM: (source: http://dotnet.dzone.com/articles/playing-media-content-windows)
player.CurrentStateChanged += player_CurrentStateChanged;
[...]
void player_CurrentStateChanged(object sender, RoutedEventArgs e)
{
var mediaPlayer = sender as MediaElement;
if (mediaPlayer != null && mediaPlayer.CurrentState == MediaElementState.Playing)
{
var duration = mediaPlayer.NaturalDuration.TimeSpan.TotalSeconds;
ThreadingHelper.ExecuteAsyncAction(() =>
{
do
{
ThreadingHelper.ExecuteOnUiThread(() =>
{
Progress = mediaPlayer.Position.TotalSeconds * 100 / duration;
});
Thread.Sleep(10);
} while (IsPlaying);
});
}
}
and xaml:
<!--TITLE-->
<TextBlock Text="{Binding Sound.Libelle}"
Style="{StaticResource PhoneTextNormalStyle}"
TextWrapping="Wrap"/>
<ProgressBar Height="20" Width="400" Value="{Binding Progress}"></ProgressBar>
The progress bar display correctly, problem is when I play a second sound, the first progress bar is also updated, due to binding with my Progress property.
I don't know how to prevent this behavior, any ideas are welcome.
EDIT: I forgot to mention that this behavior occurs only when I'm starting another sound while a first is playing. My first sound stop, the second start but both progress bar are updated
EDIT2: A little more code:
private void PlaySong()
{
MediaElement player = null; // get the media element from App resources
if (Application.Current.Resources.Contains("MediaPlayer"))
{
player = Application.Current.Resources["MediaPlayer"] as MediaElement;
}
if (player != null)
{
if (IsPlaying)
{
player.Stop();
player.MediaEnded -= player_MediaEnded;
player.CurrentStateChanged -= player_CurrentStateChanged;
}
else
{
player.Source = new Uri(Sound.Link, UriKind.Relative);
player.Play();
player.MediaEnded += (o, args) => player_MediaEnded(player, args);
player.CurrentStateChanged += player_CurrentStateChanged;
IsPlaying = true;
}
}
}
This is my PlaySong()
method called onClick
, who gets the unique MediaPlayer
defined in my app.xaml. It play or stop according to current sound state.
This is my xaml, it's a template for a <ListBox>
control bound to an ObservableCollection of SoundViewModel
<Button x:Name="SoundButton"
Command="{Binding PlaySongCommand}"
HorizontalAlignment="Stretch"
Style="{StaticResource EmptyButtonStyle}">
<StackPanel Margin="12,0,0,12">
<!--TITLE-->
<TextBlock Text="{Binding Sound.Libelle}"
Style="{StaticResource PhoneTextNormalStyle}"
TextWrapping="Wrap"/>
<ProgressBar Height="20" Width="400" Value="{Binding Progress}"></ProgressBar>
</StackPanel>
<!-- LONG HOLD GESTION-->
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu Name="AllsoundMenu" IsZoomEnabled="True">
<toolkit:MenuItem Header="Add to favorite"
Command="{Binding AddToFavoriteCommand}" />
<toolkit:MenuItem Header="Add as a ringtone" Command="{Binding AddToRingtoneCommand}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Button>
So one ProgressBar/Sound and only one MediaElement
in the app.
Hope this helps you to see clearer.
Maybe I souldn't have only one MediaElement
, but it seemed right to implement this way.