【问题标题】:UWP slider After slidingUWP 滑块 滑动后
【发布时间】:2020-07-29 19:04:05
【问题描述】:

我正在使用滑块来控制正在播放的 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);
    }

---更新---

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

    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");
    }

【问题讨论】:

  • 请提供您的代码,看看我们如何帮助您解决问题
  • @sayahimad 我不确定要放什么代码,因为我只是在寻找一些事件而不是调试我的模式。

标签: c# xaml uwp slider


【解决方案1】:

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;
            }
        }

【讨论】:

  • 谢谢!这正是我要找的!
  • 我还有一个问题。你如何判断是拖动事件还是点击事件被触发?点击事件似乎没有触发ManipulationCompleted
  • 如果要判断点击事件,可以添加Tapped事件,如:.When你点击,事件就会被触发。你可以像 ManipulationCompleted 一样做同样的操作。
  • 很抱歉再次打扰您,但我有一些不知道如何解决的冲突。能否请您看一下更新区?
  • 我也发现了这个问题,我已经更新了答案,只是一个想法或建议。
【解决方案2】:

没有什么比 ValueChanged 事件更有效的了。它工作得太好了,而且被调用得太频繁了。在这些情况下,我有一个实用方法,它接受一个代码块并在用户做出决定时运行它:

public static class Utility
{
    private static DispatcherTimer settledTimer;
    public delegate void SettledCallback( );
    public static void RunWhenSettled(SettledCallback callback)
    {
        if (settledTimer == null)
        {
            settledTimer = new DispatcherTimer( );
            settledTimer.Interval = TimeSpan.FromSeconds(.4);
            settledTimer.Tick += delegate
            {
                settledTimer.Stop( );
                callback( );
                settledTimer = null;
            };
            settledTimer.Start( );
        }
        else if (settledTimer.IsEnabled)
            settledTimer.Start( );   // resets the timer...
    }
}

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

【讨论】:

    【解决方案3】:

    ManipulationStartedManipulationCompleted 添加事件处理程序。不要忘记也设置 ManipulationMode。例如。 ManipulationMode="全部"。

        private bool dragStarted = false;
    
        private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (!dragStarted)
            {
                // Do work
            }
        }
    
        private void Slider_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {
            dragStarted = true;
        }
    
        private void Slider_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            // Do work
            dragStarted = false;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 2016-04-20
      • 1970-01-01
      相关资源
      最近更新 更多