媒体元素和进度条Windows手机
本文关键字:Windows 手机 元素 媒体 | 更新日期: 2023-09-27 17:49:58
我想播放声音,并在每个声音下方显示进度条我在我的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属性。
我不知道如何防止这种行为,欢迎提出任何建议。
编辑:我忘了提到,这种行为只发生在我开始另一个声音,而第一个正在播放。我的第一个声音停止,第二个开始,但两个进度条都更新了
edit: A little more code:
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
,但它似乎是正确的实现这种方式。
我认为你应该尝试从'播放器'对象删除处理程序时,声音不运行。我希望它会有所帮助。这样的:
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;
}
...
}