C# Windows phone 8滑块绑定仅在单击后工作

C# Windows phone 8滑块绑定仅在单击后工作,c#,windows-phone-8,slider,mediaelement,C#,Windows Phone 8,Slider,Mediaelement,我正在Windows Phone 8上编写一个音频应用程序。我已经创建了一个MediaElement和一个搜索栏(滑块): 以下是CurrentStateChanged事件代码: private void GetTrackDuration(object sender, RoutedEventArgs e) { var player = (MediaElement)sender; if (player.CurrentState == System.Windows.Media.Med

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

以下是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;
}
这一切似乎工作正常,但有一个问题,绑定到滑块-它不会更新,直到我点击应用程序内的某个地方-我的意思是,我可能会点击一个按钮,没有连接到滑块或媒体元素或在一个空的空间。单击后,滑块正在更新,一切正常。顺便说一句,音乐播放正常-即使在开始时滑块没有被更新。我试着上网,但是我不知道该问什么,这就是为什么我请求你的帮助。如果有人知道我在哪里可以找到解决方案,我将非常感激!:)


提前感谢您的帮助

当滑块获得焦点时,这看起来像是个问题,我试图找到一个重定向焦点的解决方案,但到目前为止,我还没有找到。相反,我提出了一个不同的建议,并对您的代码进行了一些评论:

  • 在媒体打开而不是播放状态更改时获取曲目持续时间:

    private void player_MediaOpened(object sender, RoutedEventArgs e)
    {
        playerSeekBar.Maximum = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
    }
    
  • 您的滑块可能会随着MediaElement位置的每一点变化而更新。我认为这是不必要的-它可以更新,例如每秒钟。因此,我的建议是-将滑块绑定到属性,并每秒通知PropertyChanged(使用
    Dispatchermer
    ):

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

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

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

    希望这有帮助。

    非常感谢您的回答!我尝试使用您所说的,但是出现了一个小问题-当我将事件从CurrentStateChanged更改为MediaOpen时,滑块移动太快,结束得太快。现在我不知道为什么会这样。还是谢谢你的帮助!:)@罗曼蒂佩斯:这很奇怪,我已经检查过了,应该可以用了。请在调试模式下检查传递给Slider.Maximum的值。@RomanyTypes我添加了另一种管理Slider的方法-如果您不需要绑定。非常感谢您的帮助-您的代码运行良好,这是我的错误-我使用不同的URI分配了两次player.Source。@RomanyTypes欢迎您。谢谢你提供的信息。祝你幸福快乐。
    // 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.
    }
    
    <MediaElement x:Name="player" MediaOpened="player_MediaOpened"/>
    <Slider x:Name="playerSeekBar" Value="{Binding SlideValue, Mode=TwoWay}" SmallChange="1" LargeChange="1"/>
    
    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.
        }
    }
    
    <MediaElement x:Name="player" MediaOpened="player_MediaOpened"/>
    <Slider x:Name="playerSeekBar" Value="0" SmallChange="0.01" Maximum="1.0"/>