从数字向上排除某些值

时间:2014-08-18 14:44:42

标签: c# numericupdown

我在.net 4.5.2中使用带有VS2013的C#。

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

4 个答案:

答案 0 :(得分:2)

您想验证输入是否在您想要的数字集中。

所以..我会做这样的事情。这只是一个普遍的想法,但应该做你需要的。数字%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
       }
    }
}

答案 1 :(得分:2)

您可以像这样创建自定义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;
        }
    }
}

注意:这会拧紧Acceleration功能。并且需要更多努力来响应在运行时更改的Maximum属性。

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

答案 2 :(得分:1)

我只想使用一个组合框,并使用嵌入在for循环中的if语句填充组合框

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

答案 3 :(得分:0)

我的自定义类:

    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事件。

问题:

  • 通过键入设置不相关的值并且控件将该值更改为最接近的值并且与先前的值相等时,将触发值更改事件。

用法:

  • 将控件放到窗体上。
  • 设置“可能的值”数组:

    NumericUpdownCustom1.PossibleValues =新的十进制[] {1,10,20,33,55};