gpt4 book ai didi

c# - Windows Phone 8 slider 绑定(bind)仅在单击后起作用

转载 作者:太空宇宙 更新时间:2023-11-03 13:26:51 24 4
gpt4 key购买 nike

我正在 Windows Phone 8 上编写一个音频应用程序。我创建了一个 MediaElement 和一个搜索栏( slider ):

<MediaElement x:Name="player" CurrentStateChanged="GetTrackDuration" />
<Slider x:Name="playerSeekBar" Value="{Binding ElementName=player, Path=Position,
Mode=TwoWay, Converter={StaticResource PositionConverter}}" SmallChange="1" LargeChange="1"/>

这是我的转换器代码:

public class PositionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double position = 0;
TimeSpan timespan = TimeSpan.Parse(value.ToString());
position = timespan.TotalSeconds;

return position;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return TimeSpan.FromSeconds((double)value);
}
}

这是 CurrentStateChanged 事件代码:

private void GetTrackDuration(object sender, RoutedEventArgs e)
{
var player = (MediaElement)sender;
if (player.CurrentState == System.Windows.Media.MediaElementState.Playing)
playerSeekBar.Maximum = player.NaturalDuration.TimeSpan.TotalSeconds;
}

一切似乎都正常,但是绑定(bind)到 slider 有一个问题 - 它不会更新,直到我点击应用程序内部的某个地方 - 我的意思是我可能会点击一个未与 slider 连接的按钮或媒体元素或空白空间。单击 slider 后, slider 正在更新,一切正常。顺便说一句,音乐播放正常 - 即使在 slider 未更新的开始时也是如此。我试图在互联网上查看,但是我不确定要问什么,这就是为什么我向您寻求帮助。如果有人知道我可以在哪里搜索解决方案,我将不胜感激!:)

提前感谢您的帮助!

最佳答案

当 Slider 获得 Focus 时看起来像个问题,我试图找到重定向 Focus 的解决方案,但到目前为止 - 我还没有找到它。相反,我有一个不同的建议和对您的代码的一些评论:

  1. 在媒体打开时而不是在 PlayState 更改时获取轨道持续时间:

    private void player_MediaOpened(object sender, RoutedEventArgs e)
    {
    playerSeekBar.Maximum = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
    }
  2. 您的 Slider 可能会随着 MediaElement 位置的每次微小变化而更新。我认为这不是必需的 - 它可以每秒更新一次。所以我的建议是 - 将您的 Slider 绑定(bind)到一个属性,并每秒通知一次 PropertyChanged(使用 DispatcherTimer):

    // In this case we need INotifyPropertyChanged - 
    public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
    {

    // implementing interface
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaiseProperty(string property = null)
    {
    if (this.PropertyChanged != null)
    this.PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    // Property for Binding
    public double SlideValue
    {
    get { return player.Position.TotalSeconds; }
    set { player.Position = TimeSpan.FromSeconds(value); }
    }

    DispatcherTimer timer = new DispatcherTimer(); // timer

    // Get the duration when Media File is opened
    private void player_MediaOpened(object sender, RoutedEventArgs e)
    {
    playerSeekBar.Maximum = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
    }

    public MainPage()
    {
    InitializeComponent();
    this.DataContext = this; // Set the DataContext
    Play.Click += Play_Click; // My play method
    timer.Interval = TimeSpan.FromSeconds(1);
    timer.Tick += (s, e) => { RaiseProperty("SlideValue"); };
    }

    private void Play_Click(object sender, RoutedEventArgs e)
    {
    player.AutoPlay = true;
    player.Source = new Uri("music.mp3", UriKind.RelativeOrAbsolute);
    timer.Start(); // DON'T forget to start the timer.
    }

在这种情况下,您不再需要转换器,您的 XAML 代码可能如下所示:

<MediaElement x:Name="player" MediaOpened="player_MediaOpened"/>
<Slider x:Name="playerSeekBar" Value="{Binding SlideValue, Mode=TwoWay}" SmallChange="1" LargeChange="1"/>

上面的代码可能还需要一些改进,但工作得很好。

编辑 - 没有 DataBinding 和 INotifyPropertyChanged 的​​方法

您还可以在不使用绑定(bind)的情况下以更简单的方式完成您的任务,只需使用 TimerLostMouseCapture:

public partial class MainPage : PhoneApplicationPage
{
private double totalSeconds = 1;

DispatcherTimer timer = new DispatcherTimer();

private void player_MediaOpened(object sender, RoutedEventArgs e)
{
totalSeconds = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
}

public MainPage()
{
InitializeComponent();
Play.Click += Play_Click;
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += (s, e) => { playerSeekBar.Value += (double)(1 / totalSeconds); };
playerSeekBar.LostMouseCapture += (s, e) =>
{ player.Position = TimeSpan.FromSeconds(playerSeekBar.Value * totalSeconds); };
}

private void Play_Click(object sender, RoutedEventArgs e)
{
player.AutoPlay = true;
player.Source = new Uri("music.mp3", UriKind.RelativeOrAbsolute);
timer.Start(); // DON'T forget to start the timer.
}
}

在 XAML 中:

<MediaElement x:Name="player" MediaOpened="player_MediaOpened"/>
<Slider x:Name="playerSeekBar" Value="0" SmallChange="0.01" Maximum="1.0"/>

希望这对您有所帮助。

关于c# - Windows Phone 8 slider 绑定(bind)仅在单击后起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22115537/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com