首页 > 解决方案 > UWP 滑块 滑动后

问题描述

我正在使用滑块来控制正在播放的 MediaElement 的位置。我已经实现了 ValueChanged 事件来同步滑块的位置和值。因此,当我在 Thumb 上拖动时,MediaElement 的位置也会发生变化。但是,这会造成糟糕的用户体验。理想的情况应该是,在用户完成滑动后,MediaElement 会跳转到最终位置。所以我正在寻找像 AfterSliding 这样的事件/处理程序。

我见过像使用 OnThumbDragCompleted 这样的解决方案。但是,这些问题是关于 WPF 的,我在 UWP 中找不到这样的问题。有人有解决方法吗?

当前的:

    private void ProgressBar_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
    {
        MediaPlayer.Position = TimeSpan.FromSeconds(e.NewValue);
        LeftTimeTextBlock.Text = MusicDurationConverter.ToTime((int)e.NewValue);
    }

预期的:

    private void ProgressBar_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
    {
        if (!isDragging || slidingFinished) MediaPlayer.Position = TimeSpan.FromSeconds(e.NewValue);
        LeftTimeTextBlock.Text = MusicDurationConverter.ToTime((int)e.NewValue);
    }

- -更新 - -

我有一个每秒滴答的计时器,但是当我点击滑块(不是拇指)区域时,并不总是触发点击事件,因此拇指会在点击的位置和它的新位置之间来回移动。我该如何解决它,以便当用户仍然握住拇指时,它会保持在点击位置?我想点击的事件可能不是我应该使用的。

    public void Tick()
    {
        if (ShouldUpdate && !SliderClicked)
        {
            MediaSlider.Value = MediaControl.Player.PlaybackSession.Position.TotalSeconds;
        }
        SliderClicked = false;
    }

    private void MediaSlider_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Debug.WriteLine("Tapped");
        MediaControl.SetPosition(MediaSlider.Value);
        SliderClicked = true;
    }

    private void MediaSlider_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
    {
        MediaControl.SetPosition(MediaSlider.Value);
        ShouldUpdate = true;
        Debug.WriteLine("Completed");
    }

    private void MediaSlider_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
    {
        ShouldUpdate = false;
        Debug.WriteLine("Started");
    }

标签: c#xamluwpslider

解决方案


Slider 有ManipulationCompleted事件。当对 UIElement 的操作完成时发生。您可以订阅它以监听 Slider 是否完成。同时,如果要处理操作,您需要将ManipulationMode设置为 System 或 None 以外的值事件。

在 XAML 中:

<Slider Name="timelineSlider" ManipulationCompleted="Slider_ManipulationCompleted" ManipulationMode="All" ValueChanged="SeekToMediaPosition" />

在 C# 中:

private void Slider_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {​
            Slider MySlider = sender as Slider;​
            myMediaElement.Position = TimeSpan.FromSeconds(MySlider.Value);​
            LeftTimeTextBlock.Text = MusicDurationConverter.ToTime((int)e.NewValue);​
        }

更新:

可以订阅ValueChanged和ManipulationStarting事件。我发现当你拖动Thumb时,它会先触发starting事件,然后是valuechanged。如果你只点击,它会先触发valuechange然后starting事件。

在 XAML 中:

<Slider Name="timelineSlider" ManipulationStarting="TimelineSlider_ManipulationStarting"  ManipulationCompleted="Slider_ManipulationCompleted" ManipulationMode="All" ValueChanged="SeekToMediaPosition" Width="70"/>

在 C# 中:

您可以声明一个oldValue属性来保存Slider的值。触发启动事件时,可以比较oldValue和当前值。如果相等,则拖动Thumb。

private double oldValue;

private void SeekToMediaPosition(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (isTap==true)
            {
                ...//tap
            }
            else
            {

            }
            oldValue = timelineSlider.Value;
        }
private void Slider_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {

            Slider MySlider = sender as Slider;
            double s = MySlider.Value;
            isTap = true;
        }

        private void TimelineSlider_ManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
        {
            if (oldValue == timelineSlider.Value) {
                //tuozhuai
                isTap = false;
            }
            else{
                isTap = true;
            }
        }

推荐阅读