0

我想播放声音,并在每个声音下方显示一个进度条由于我的 VM 中的这一点,我正在显示当前进度:(来源:http ://dotnet.dzone.com/articles/playing-media-content-窗户

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

和 xml:

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

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

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

<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,但以这种方式实施似乎是正确的。

4

1 回答 1

0

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

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

        }
    }

xml:

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

视图模型:

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;

        }
     ...
     }
于 2012-12-31T07:12:38.657 回答