如何从扩展WPF工具包创建循环doubleUpDown?

时间:2016-08-10 10:35:27

标签: c# wpf wpf-extended-toolkit

我有一个任务,我应该创建一个数字微调器,如果选中一个复选框,它也会循环通过最大最小值,这是从扩展的WPF Toolkit的doubleUpDown派生的。有没有办法可以理解增量旋转按钮或减少旋转按钮被推?那么我可以为我的数字微调器提供所需的控件吗?

Documentation of DoubleUpDown

我创建了一个数字微调器,但只使用WPF,我应该使用扩展工具包。

enter image description here

1 个答案:

答案 0 :(得分:0)

似乎DoubleUpDown不提供上/下按钮点击的事件。但是(来自Documentation you linked):

  

ValueChanged:值更改时引发。 (继承自UpDownBase)

值已更改事件可以帮助您。在这种情况下,您可以尝试将最小值始终设置为低1,将最大值设置为高于用户在文本框中输入的值,并在ValueChanged事件中检查这些值以实现“循环”。不过,这不是最漂亮的解决方案。

我创建了一个小例子。相关的xaml:

<xctk:DoubleUpDown x:Name="Spinner" ClipValueToMinMax="True" Minimum="9" Maximum="21" Value="15" Increment="{Binding ElementName=Increment, Path=Text}" ValueChanged="UpDownBase_OnValueChanged"/>
<TextBox x:Name="Min" TextChanged="Min_OnTextChanged" Text="10"/>
<TextBox x:Name="Max" TextChanged="Max_OnTextChanged" Text="20"/>
<TextBox x:Name="Increment" Text="1"/>

背后的代码(xaml.cs):

private void UpDownBase_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    if ((double) e.NewValue == Spinner.Minimum)
        Spinner.Value = Spinner.Maximum - 1;
    else if ((double) e.NewValue == Spinner.Maximum)
        Spinner.Value = Spinner.Minimum + 1;
}

private void Min_OnTextChanged(object sender, TextChangedEventArgs e)
{
    double minimum;
    if (double.TryParse(Min.Text, out minimum))
        Spinner.Minimum = minimum - 1;
}

private void Max_OnTextChanged(object sender, TextChangedEventArgs e)
{
    double maximum;
    if (double.TryParse(Max.Text, out maximum))
        Spinner.Maximum = maximum + 1;
}

然而,最大的问题是,除了1之外的增量值,它不能很好地工作。例如,如果你处于最低限度并希望减少一个以上,它仍然会达到最大值。更糟糕的是,当使用小于1的增量时,yo可以低于最小值,直到增量达到我们用来检查它的minimum - 1。因此,如果你想允许双打而不仅仅是整数,那么这个解决方案根本不适合你。

我认为最好的解决方案是像你一样创建自己的UserControl,因为你试图显着改变原始功能。为什么需要使用DoubleUpDown?

另一种方法是根本不使用最小和最大属性,并在每次ValueChanged事件发生时自己处理计算 - 这将解决上述解决方案的问题。

XAML:

<xctk:DoubleUpDown x:Name="Spinner" Value="15" Increment="{Binding ElementName=Increment, Path=Text}" ValueChanged="UpDownBase_OnValueChanged"/>
<TextBox x:Name="Min" TextChanged="Min_OnTextChanged"/>
<TextBox x:Name="Max" TextChanged="Max_OnTextChanged"/>
<TextBox x:Name="Increment" Text="1"/>

xaml.cs

public MainWindow()
{
    InitializeComponent();
    Min.Text = _currentMinimum.ToString();
    Max.Text = _currentMaximum.ToString();
}

private double _currentMinimum = 10;
private double _currentMaximum= 100;

private void UpDownBase_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    if ((double) e.NewValue < _currentMinimum)
        Spinner.Value = (double)e.NewValue + (_currentMaximum - _currentMinimum);
    else if ((double) e.NewValue > _currentMaximum)
        Spinner.Value = (double)e.NewValue - (_currentMaximum - _currentMinimum);
}

private void Min_OnTextChanged(object sender, TextChangedEventArgs e)
{
    double minimum;
    if (double.TryParse(Min.Text, out minimum))
        _currentMinimum = minimum;
}

private void Max_OnTextChanged(object sender, TextChangedEventArgs e)
{
    double maximum;
    if (double.TryParse(Max.Text, out maximum))
        _currentMaximum= maximum;
}