从数字上下排除某些值

本文关键字:排除 上下 数字 数字上 | 更新日期: 2023-09-27 18:18:43

我在。net 4.5.2中使用c#和VS2013。

基本上,我有一个数字上下向下,用户可以从中选择某些值。但是,我希望唯一可选择的值是1、2、3、4、6、12和24的倍数。有什么东西可以做到这一点,或者只是有一个组合框会更简单吗?

从数字上下排除某些值

您可以创建一个自定义的NumericUpDown

class CustomNumericUpDown : NumericUpDown
{
    private int currentIndex = 0;
    private decimal[] possibleValues = null;
    public decimal[] PossibleValues
    {
        get
        {
            if (possibleValues == null)
            {
                possibleValues = GetPossibleValues().ToArray();
            }
            return possibleValues;
        }
    }
    public override void UpButton()
    {
        if (base.UserEdit)
        {
            this.ParseEditText();
        }
        var values = PossibleValues;
        this.currentIndex = Math.Min(this.currentIndex + 1, values.Length - 1);
        this.Value = values[this.currentIndex];
    }
    public override void DownButton()
    {
        if (base.UserEdit)
        {
            this.ParseEditText();
        }
        var values = PossibleValues;
        this.currentIndex = Math.Max(this.currentIndex - 1, 0);
        this.Value = values[this.currentIndex];
    }
    private IEnumerable<decimal> GetPossibleValues()
    {
        foreach (var value in new decimal[] { 1, 2, 3, 4, 6, 12 })
        {
            yield return value;
        }
        for (decimal i = 24; i < Maximum; i += 24)
        {
            yield return i;
        }
    }
}

注意:这将关闭加速功能。并且需要更多的努力来响应运行时Maximum属性的变化。

同样值得注意的是,如果Maximum值非常大,这将创建一个巨大的数组。对于较小的值,这很好。要摆脱这个数组,您需要自己的状态机实现。

您需要验证输入是否是所需的一组数字。

. .我会这样做。这只是一个大概的想法,但应该能满足你的需要。数字% 24 == 0可以表示24、48、72等。

List<int> acceptedValues = new List<int>(){ 1, 2, 3, 4, 6, 12 };
private void numericUpDown1_KeyUp(object sender, KeyEventArgs e)
{
    int number = (int)numericUpDown1.Value;
    if (acceptedValues.Contains(number) || (number % 24 == 0))
    {
       // is good
    }
}
private void numericUpDown1_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right) 
    {
       int number = numericUpDown1.Value;
       if (acceptedValues.Contains(number) || (number % 24 == 0))
       {
          // is good
       }
    }
}

我将使用一个组合框,并在组合框中嵌入if语句

for循环
for(int I = 0; I < 100; I++)
{ 
    if((I == 1) || (I == 2) || etc.... || (I % 24 == 0))
    {
        //populate combo box with this value
    }
 }

我的自定义类:

    class NumericUpdownCustom : NumericUpDown
{
    private decimal[] possibleValues = null;
    public decimal[] PossibleValues
    {
        get
        {
            return possibleValues;
        }
        set
        {
            possibleValues = value;
            FillDefaultValues();
            this.Value = possibleValues.Min();
        }
    }
    public NumericUpdownCustom() : base()
    {
        FillDefaultValues();
        this.Value = PossibleValues.Min();    
    }
    private void FillDefaultValues() {
        if (PossibleValues == null) {
            List<decimal> items = new List<decimal>();
            for (decimal i = this.Minimum; i <= this.Maximum; i++)
            {
                items.Add(i);
            }
            PossibleValues = items.ToArray();
        }
    }
    public override void UpButton()
    {
        if (base.UserEdit)
        {
            this.ParseEditText();
        }
        decimal number = (decimal)this.Value;
        if (PossibleValues.Any(a => a > number))
        {
            this.Value = PossibleValues.Where(w => w > number).Min();
        }
        else
        {
            this.Value = PossibleValues.Max();
        }
    }
    public override void DownButton()
    {
        if (base.UserEdit)
        {
            this.ParseEditText();
        }
        decimal number = (decimal)this.Value;
        if (PossibleValues.Any(a => a < number))
        {
            this.Value = PossibleValues.Where(w => w < number).Max();
        }
        else
        {
            this.Value = PossibleValues.Min();
        }
    }
    public new decimal Value
    {
        get
        {
            decimal desiredValue = base.Value;
            if (!PossibleValues.Contains(desiredValue))
            {
                var nearest = PossibleValues.Aggregate((current, next) => Math.Abs((long)current - desiredValue) < Math.Abs((long)next - desiredValue) ? current : next);
                SetValueWithoutRaisingEvent(nearest);
            }
            return base.Value;
        }
        set
        {
            if (!PossibleValues.Contains(value))
            {
                var nearest = PossibleValues.Aggregate((current, next) => Math.Abs((long)current - value) < Math.Abs((long)next - value) ? current : next);
                base.Value = nearest;
            }
            else
            {
                if (value < this.Minimum)
                {
                    base.Value = this.Minimum;
                }
                else if (value > this.Maximum)
                {
                    base.Value = this.Maximum;
                }
                else
                {
                    base.Value = value;
                }
            }
        }
    }
    private void SetValueWithoutRaisingEvent(decimal value) {
        var currentValueField = GetType().BaseType.GetRuntimeFields().Where(w => w.Name == "currentValue").FirstOrDefault();
        if (currentValueField != null)
        {
            currentValueField.SetValue(this, value);
            this.Text = value.ToString();
        }
    }
}

没有完全测试过(例如使用数据绑定),但是:

  • 如果没有设置可能的值,则在最小值和最大值之间使用正常值。
  • 可以通过输入或编程方式更改值。如果可能值数组不包含给定值,则该值将是最接近的值。
  • 当程序更改值为不可能的值时,删除重复的ValueChanged事件。

问题:

  • 当您使用键入设置不相关的值并且控件将此值更改为最接近的值并且与前一个值相等时,将触发值更改事件。

用法:

  • 将控件放置到表单中。
  • 设置PossibleValues数组:

    NumericUpdownCustom1。