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

およびxaml:

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

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

進行状況バーが正しく表示されます。問題は、2 番目のサウンドを再生すると、進行状況プロパティとのバインドにより、最初の進行状況バーも更新されることです。

この動作を防ぐ方法がわかりません。どんなアイデアでも大歓迎です。

編集: この動作は、最初のサウンドの再生中に別のサウンドを開始している場合にのみ発生することを忘れていました。私の最初の音停止、2 番目の開始が、両方の進行状況バーが更新されます

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

これは、私の app.xaml で定義された一意のものを取得する という私のPlaySong()メソッドです。現在のサウンド状態に応じて再生または停止します。onClickMediaPlayer

これは私の 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 は 1 つMediaElement、アプリには 1 つだけです。これがより明確に見えるようになることを願っています。

たぶんMediaElement、私は を 1 つしか持っていないかもしれませんが、この方法で実装するのは正しいように思えました。

4

1 に答える 1

0

サウンドが実行されていないときは、「player」オブジェクトからハンドラーを削除する必要があると思います。お役に立てば幸いです。このような:

 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;

        }
     ...
     }
于 2012-12-31T07:12:38.657 に答える