繁体   English   中英

媒体元素和进度栏Windows Phone

[英]Media Element and Progress Bar Windows phone

我想播放声音,并在每个声音的下方显示一个进度条,这要感谢我在VM中显示的当前进度:(来源: 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);
                });
        }
    }

和xaml:

<!--TITLE-->
                <TextBlock Text="{Binding Sound.Libelle}"
                           Style="{StaticResource PhoneTextNormalStyle}"
                           TextWrapping="Wrap"/>

            <ProgressBar Height="20" Width="400" Value="{Binding Progress}"></ProgressBar>

进度条正确显示,问题是当我播放第二声音时,由于与我的Progress属性绑定,第一进度条也被更新了。

我不知道如何防止这种行为,欢迎提出任何想法。

编辑:我忘了提到,只有当我在播放第一个声音的同时开始播放另一个声音时,才会出现这种现象。 我的第一个声音停止,第二个开始,但是两个进度条都更新了

EDIT2:更多代码:

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

这是我的称为onClick PlaySong()方法,该方法获得了我app.xaml中定义的唯一MediaPlayer 根据当前的声音状态播放或停止。

这是我的xaml,它是绑定到SoundViewModel的ObservableCollection的<ListBox>控件的模板

<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>

因此,应用程序中只有一个ProgressBar / Sound,只有一个MediaElement 希望这可以帮助您看得更清楚。

也许我没有一个MediaElement ,但是以这种方式实现似乎是正确的。

我认为您应该在声音不运行时尝试从“玩家”对象中删除处理程序。 我希望这会有所帮助。 像这样:

 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(() =>
                        {
                            //A list of values , nowPlay means that the sound you are playing
                            ProgressList[nowPlay] = mediaPlayer.Position.TotalSeconds * 100 / duration;
                        });
                        Thread.Sleep(10);
                    } while (IsPlaying);
                });

        }
    }

xaml:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <phone:LongListSelector x:Name="MainLongListSelector" Margin="0,0,-12,0" ItemsSource="{Binding ProgressList}" SelectionChanged="MainLongListSelector_SelectionChanged">
            <phone:LongListSelector.ItemTemplate>
                <DataTemplate>
                  <StackPanel Margin="0,0,0,17">
                        <ProgressBar Height="20" Width="400" Value="{Binding Values}"/>
                  </StackPanel>
                </DataTemplate>
            </phone:LongListSelector.ItemTemplate>
        </phone:LongListSelector>
    </Grid>

ViewModel:

public class Progress : INotifyPropertyChanged
    {
        int _values;
        public int Values
        {
            get
            {
                return _values;
            }
            set
            {
                if (value != _values)
                {
                    _values = value;
                    NotifyPropertyChanged("Values");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

 public class MainViewModel : INotifyPropertyChanged
    {
        List<Progress> _progress = new List<Progress>();
        int _values = 100;
        public MainViewModel()
        {
            this.Items = new ObservableCollection<ItemViewModel>();
            _progress.Add(new Progress());
            _progress.Add(new Progress());
            _progress[0].Values = 50;
            _progress[1].Values = 100;

        }
     ...
     }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM