[英]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.