Events 如何收听UWP Xaml滑块操纵开始/结束事件?

Events 如何收听UWP Xaml滑块操纵开始/结束事件?,events,uwp,slider,uwp-xaml,Events,Uwp,Slider,Uwp Xaml,我应该在UWP Xaml滑块上监听哪些事件,以确定用户何时开始和结束操作 当您有一个代表某些不断变化的应用程序状态(例如,动画时间)的滑块,并且希望在用户与滑块交互时暂停更新时,此功能非常重要 WPF和Windows Phone已经回答了这个问题,但UWP没有。其他解决方案对于UWP不起作用或不完整。您需要从滑块模板的两个元素(拇指和容器)中侦听交互事件。这是因为用户可以通过单击和拖动拇指来直接操纵拇指,但也可以单击滑块上的任何位置,拇指将跳到该位置(尽管看起来您正在操纵拇指,但实际上每次鼠标移

我应该在UWP Xaml滑块上监听哪些事件,以确定用户何时开始和结束操作

当您有一个代表某些不断变化的应用程序状态(例如,动画时间)的滑块,并且希望在用户与滑块交互时暂停更新时,此功能非常重要


WPF和Windows Phone已经回答了这个问题,但UWP没有。其他解决方案对于UWP不起作用或不完整。

您需要从滑块模板的两个元素(拇指和容器)中侦听交互事件。这是因为用户可以通过单击和拖动拇指来直接操纵拇指,但也可以单击滑块上的任何位置,拇指将跳到该位置(尽管看起来您正在操纵拇指,但实际上每次鼠标移动时拇指都会重新定位-您仍在与容器交互)

这里有几个警告:

  • thumb和容器都处理它们的输入事件,并且不传递它们,因此您需要使用附加RouteEvent处理程序的AddHandler方法,以便获得已经处理的事件

  • 您需要在应用控件模板后附加事件处理程序,这意味着您需要对滑块进行子类化以覆盖受保护的方法

此处介绍RouteEvent处理程序信息:

以下SliderEx类添加了一些事件,可用于检测用户何时开始/结束与滑块的交互:

public class SliderEx : Slider
{
    public event EventHandler SliderManipulationStarted;
    public event EventHandler SliderManipulationCompleted;
    public event EventHandler SliderManipulationMoved;
    private bool IsSliderBeingManpulated
    {
        get
        {
            return this.isContainerHeld || this.isThumbHeld;
        }
    }


    private bool isThumbHeld = false;
    private bool isContainerHeld = false;

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        var thumb = base.GetTemplateChild("HorizontalThumb") as Thumb;
        if (thumb == null)
        {
            thumb = base.GetTemplateChild("VerticalThumb") as Thumb;
        }
        if (thumb != null)
        {
            thumb.DragStarted += this.Thumb_DragStarted;
            thumb.DragCompleted += this.Thumb_DragCompleted;
            thumb.DragDelta += this.Thumb_DragDelta;
        }

        var sliderContainer = base.GetTemplateChild("SliderContainer") as Grid;
        if (sliderContainer != null)
        {
            sliderContainer.AddHandler(PointerPressedEvent, 
                new PointerEventHandler(this.SliderContainer_PointerPressed), true);
            sliderContainer.AddHandler(PointerReleasedEvent, 
                new PointerEventHandler(this.SliderContainer_PointerReleased), true);
            sliderContainer.AddHandler(PointerMovedEvent, 
                new PointerEventHandler(this.SliderContainer_PointerMoved), true);
        }
    }

    private void SliderContainer_PointerMoved(object sender, 
        Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
    {
        this.InvokeMove();
    }

    private void SliderContainer_PointerReleased(object sender, 
        Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
    {
        this.SetContainerHeld(false);
    }

    private void SliderContainer_PointerPressed(object sender, 
        Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
    {
        this.SetContainerHeld(true);
    }

    private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
        this.InvokeMove();
    }

    private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
    {
        this.SetThumbHeld(false);
    }

    private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
    {
        this.SetThumbHeld(true);
    }

    private void SetThumbHeld(bool held)
    {
        bool wasManipulated = this.IsSliderBeingManpulated;
        this.isThumbHeld = held;
        this.InvokeStateChange(wasManipulated);
    }

    private void SetContainerHeld(bool held)
    {
        bool wasManipulated = this.IsSliderBeingManpulated;
        this.isContainerHeld = held;
        this.InvokeStateChange(wasManipulated);
    }

    private void InvokeMove()
    {
        this.SliderManipulationMoved?.Invoke(this, EventArgs.Empty);
    }

    private void InvokeStateChange(bool wasBeingManipulated)
    {
        if (wasBeingManipulated != this.IsSliderBeingManpulated)
        {
            if (this.IsSliderBeingManpulated)
            {
                this.SliderManipulationStarted?.Invoke(this, EventArgs.Empty);
            }
            else
            {
                this.SliderManipulationCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
    }
}

如果您已经回答了自己的问题,请不要忘记通过以下方法关闭此线程:做得好,它成功了!实际上,我只需要sliderContainer处理程序。@Chris Caulfield在操作完成后如何获得指针的位置?实际上
操作*
是正确的方法: