WPF中的Resettable RangeBase(Slider)

时间:2014-05-26 10:16:21

标签: c# wpf custom-controls

我实现了一个源自RangeBase的自定义Slider,它具有添加的ResetValue属性,可用于将Value重置为初始值。不幸的是,这需要对值源进行双重绑定,并对ResetValue使用OneTime绑定模式。

<ButtonSlider
        Minimum="0" Maximum="500" TickFrequency="1"
        Value="{Binding Path=MaxVoltageUv}"
        ResetValue="{Binding Path=MaxVoltageUv, Mode=OneTime}" />

理想情况下,它会有一个布尔依赖属性CanReset,它会在第一次绑定时捕获ResetValue(如果已启用)。我已经尝试通过捕获第一次设置值来实现它,但由于某种原因,这只在某些时候有效。

它首先覆盖ValueProperty上的元数据:

        ValueProperty.OverrideMetadata(typeof(ButtonSlider), new FrameworkPropertyMetadata(OnValueChanged, OnCoerceValue));

然后实现自定义强制和值更改处理程序。

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var buttonSlider = ((ButtonSlider)d);
        if (buttonSlider != null)
        {
            if (!buttonSlider.valueInitialized && e.NewValue is double)
            {
                buttonSlider.resetValue = (double)e.NewValue;
                buttonSlider.valueInitialized = true;
            }

            buttonSlider.CheckResetEnabled();
        }
    }

    private static object OnCoerceValue(DependencyObject d, object baseValue)
    {
        var buttonSlider = ((ButtonSlider)d);
        if (buttonSlider != null)
        {
            if(baseValue is double)
                return Math.Max(Math.Min((double)baseValue, buttonSlider.Maximum), buttonSlider.Minimum);
        }

        return DependencyProperty.UnsetValue;
    }

由于某种原因,使用值0调用OnValueChanged,而初始绑定应该是2.这似乎与数据模板有关。不在数据模板上的控件正常工作。

是否有其他方法可以捕获依赖项属性的初始值?

2 个答案:

答案 0 :(得分:0)

我的想法

  • 验证您绑定的MaxVoltageUv是否为双倍。
  • 删除依赖项属性ResetValue,它只是在尝试解决此问题时产生噪音。
  • 0可以是依赖属性的默认值,该属性在实际绑定之前设置为。为什么不将-1.0作为默认值与OnValueChanged中的逻辑一起用来检测该场景,并忽略直到找到正确的值。

答案 1 :(得分:0)

如果在XAML中设置了数据上下文和绑定,则可以使用自定义控件的Loaded事件将当前值存储为重置值。如果您的控件位于数据模板中,这也将起作用。

如果数据上下文是从代码设置的,那么只有在将控件添加到逻辑树之前设置它才会有效。