【问题标题】:Resettable RangeBase (Slider) in WPFWPF 中的可重置 RangeBase(滑块)
【发布时间】:2014-12-22 18:47:38
【问题描述】:

我已经实现了一个从 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。我尝试通过捕获第一次设置 Value 来实现它,但由于某种原因,这只在某些时候有效。

它首先覆盖 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;
    }

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

还有其他方法可以获取依赖属性的初始值吗?

【问题讨论】:

  • 您能否提供更多关于OnValueChanged 被调用而e.NewValue 为0 时的情况的详细信息?那时e.OldValue 的价值是多少?是否在该特定时刻在属性上设置了绑定,如果是,绑定源值是什么?该属性的默认值是多少?

标签: c# wpf custom-controls


【解决方案1】:

我的想法

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

【讨论】:

  • 那么问题是初始值/重置值 0 将不起作用,因为它无法从使用数据模板时得到的 0 值中看出。
  • @Wouter 这就是为什么后来我指定控件可以将其初始值设置为 -1,如果控件看到该值,它会在实际显示时变为零。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多