WPF Slider - 从UI更改值时通知

时间:2016-04-07 11:41:51

标签: c# wpf slider

我需要使用滑块控制视频位置(以及另一种情况下的文档页面)。但问题是我不知道如何判断用户(点击,拇指拖动......)或绑定是否改变了滑块值。只有当从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命令仅在用户将拇指拖动到特定位置或单击条形图时才执行。当用户在两个刻度之间点击时(因此值/拇指移动到更近的位置),命令不会被执行 - 这对我来说是一个主要问题。

1 个答案:

答案 0 :(得分:2)

不幸的是,我认为这不是一个简单的方法。我这样做的方法是根本不绑定值并将ValueChanged事件添加到滑块。然后,当您在视觉上更改滑块时需要执行某些操作时,ValueChanged中会出现这种情况。您还希望在此事件中更新包含值(未绑定)的属性。这样,滑块值和应绑定(但不是)的值始终相同,并允许您根据更改的内容指定不同的操作。

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

然后,当您直接更新未绑定属性时,请使用检查IgnoreUpdate的方法更新实际滑块值。如果IgnoreUpdate为true,则不要尝试更新未绑定的属性(这将导致无限循环,我相信)并将其设置为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);
}

不知道你为什么要这样做,但这是我能设计的最具前瞻性的方法。