Question

I'm working on a Windows Phone 8.1 project that utilizes a background task for playing audio, and I want to bind a UI element to a property of the BackgroundMediaPlayer.Current (that's a MediaPlayer class.)

In my Xaml code I have this TextBlock Element

<TextBlock x:Name="CurrentTime" FontSize="12" HorizontalAlignment="left"
           Text="{Binding Position, Converter={StaticResource TimeSpanConverter}}"
           Style="{StaticResource ListViewItemSubheaderTextBlockStyle}"/>

Here's the converter class:

class TimeSpanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (!(value is TimeSpan))
        {
            return String.Empty;
        }

        return ((TimeSpan)value).ToString("mm':'ss");

    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

And in my code behind I set the data context of the TextBlock like this:

MediaPlayer _mediaPlayer = BackgroundMediaPlayer.Current;
CurrentTime.DataContext = _mediaPlayer;

The problem is, my control in the user interface doesn't update with the value of the MediaPlayer.Position, what's wrong with my code? thanks for the help.

Was it helpful?

Solution

So for anyone coming back to this question, I've asked on the MSDN forums and got this answer:

Unfortunately this behavior is by design. The MediaPlayer does not participate in the XAML visual tree. Because of this is it not derived from "DependencyObject" like the MediaElement is. Because of this you will not be able to bind to "MediaPlayer.Position" (normally you shouldn't do this anyway because it can cause performance problems). You will need to setup a periodic timer and poll for the current position.

http://social.msdn.microsoft.com/Forums/en-US/6e87652e-4823-4ef8-8205-dc1202d130ba/binding-to-a-backgroundmediaplayer-property?forum=wpdevelop

OTHER TIPS

So you can try this way. XAML

   <TextBlock Name="tbPlayerPosition" />
    <Slider Name="sdPlayer"
            IsHitTestVisible="False" />
    <TextBlock Name="tbRemainTime" />

CS

public DispatcherTimer _myDispatcherTimer = new DispatcherTimer();//to update player position
void PlaySong(Song song){
    sdPlayer.Minimum = 0;
    sdPlayer.Maximum = song.Duration.Ticks;
    sdPlayer.Value = MediaPlayer.PlayPosition.Ticks;
    tbPlayerPosition.Text = (new DateTime(MediaPlayer.PlayPosition.Ticks)).ToString("mm:ss");
    tbRemainTime.Text = (new DateTime(song.Duration.Ticks - MediaPlayer.PlayPosition.Ticks)).ToString("mm:ss");
    MediaPlayer.Play(song);
    StartTimer();
}
public void StartTimer(){
   _myDispatcherTimer.Start();
   _myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
   _myDispatcherTimer.Tick += OnTick;
}
public void OnTick(object o, EventArgs sender){
    Deployment.Current.Dispatcher.BeginInvoke(() => {
       if (MediaPlayer.State != MediaState.Playing){
            _myDispatcherTimer.Stop();
            _myDispatcherTimer.Tick -= OnTick;
            return;
       }

       sdPlayer.Value = MediaPlayer.PlayPosition.Ticks;
       tbPlayerPosition.Text = (new DateTime(MediaPlayer.PlayPosition.Ticks)).ToString("mm:ss");
       tbRemainTime.Text = (new DateTime(MediaPlayer.Queue.ActiveSong.Duration.Ticks - MediaPlayer.PlayPosition.Ticks)).ToString("mm:ss");
     });
     System.Diagnostics.Debug.WriteLine("UpdateTimer...");
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top