C# WPF滑块-从UI更改值时通知

C# WPF滑块-从UI更改值时通知,c#,wpf,slider,C#,Wpf,Slider,我需要用一个滑块控制视频位置(在另一种情况下也是文档页面)。但问题是,我不知道如何确定滑块值是由用户更改的(单击、拇指拖动…),还是由绑定更改的。只有当滑块值从UI更新而不是从绑定更新时,才可能触发某些事件 我实现了一个自定义滑块: public class NotifyingSlider : Slider { public static readonly DependencyProperty ValueChangedFromUIProperty = Dependenc

我需要用一个滑块控制视频位置(在另一种情况下也是文档页面)。但问题是,我不知道如何确定滑块值是由用户更改的(单击、拇指拖动…),还是由绑定更改的。只有当滑块值从UI更新而不是从绑定更新时,才可能触发某些事件

我实现了一个自定义滑块:

public class NotifyingSlider : Slider
{

    public static readonly DependencyProperty ValueChangedFromUIProperty =
        DependencyProperty.Register("ValueChangedFromUI", typeof(ICommand), typeof(NotifyingSlider));

    public ICommand ValueChangedFromUI
    {
        get
        {
            return (ICommand)GetValue(ValueChangedFromUIProperty);
        }
        set
        {
            SetValue(ValueChangedFromUIProperty, value);
        }
    }

    protected override void OnThumbDragCompleted(DragCompletedEventArgs e)
    {
        base.OnThumbDragCompleted(e);
        ValueChangedFromUI?.Execute(null);
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonUp(e);
        ValueChangedFromUI?.Execute(null);
    }
}

但是
ValueChangedFromUI
命令仅在用户将拇指拖动到特定位置或准确地单击条到勾号位置时执行。当用户在两个刻度之间单击时(因此值/拇指移动到较近的刻度),命令不会执行-这对我来说是一个主要问题。

不幸的是,我认为没有简单的方法可以做到这一点。我的方法是根本不绑定值,而是向滑块添加ValueChanged事件。然后,当滑块在视觉上发生变化时,当您需要执行某些操作时,ValueChanged中会发生一些变化。在此事件中,您还需要更新包含值(未绑定)的属性。这样,滑块值和应该绑定(但不是)的值总是相同的,并且允许您根据更改的对象指定不同的操作

您可以指定一个附加标志(bool IgnoreUpdate),在更新未绑定属性时可以将其设置为true

然后,当您直接更新未绑定属性时,使用检查IgnoreUpdate的方法更新实际滑块值。如果IgnoreUpdate为true,则不要尝试更新unbound属性(我相信这将导致无限循环),并将下一次值更改设置回false。如果为false,我们将直观地更改滑块,为了反映我们关心的属性(未绑定的属性)中的此更改,我们将对其进行更新

private bool IgnoreUpdate = false;

private int value = 0;
public int Value
{
    get
    {
        return this.value;
    } set
    {
        this.value = value;
        this.IgnoreUpdate = true;
        this.UpdateValue(value);
    }
}

public void UpdateValue(int ProgressValue)
{
    this.Slider.Value = ProgressValue;
    if (IgnoreUpdate)
    {
        IgnoreUpdate = false;
        return;
    }
    //Do stuff when the value changes visually
    this.Value = ProgressValue;
}

private void Slider_ValueChanged(object sender, ProgessChangedEventArgs e)
{
    this.UpdateValue(e.Value);
}
我不知道你为什么要这样做,但这是我能想出的最具前瞻性的方法