如何在NumericUpDown旋转框中显示不同的单位?

时间:2014-02-04 03:53:19

标签: c# .net winforms

我正在尝试创建一个控件,允许用户以他们选择的单位输入长度。为了简洁起见,我将下面的代码限制在厘米和英寸范围内,但实际上它们可以选择的单位多于那两个(2)。

我以为我可能只会影响UpdateEditText()ValidateEditText()覆盖的旋转框的显示。这就是我想出的:

public enum UnitSystem { Metric, Imperial };

public class UnitNumberUpDown : NumericUpDown
{
    public UnitNumberUpDown() { }

    private void IncrementAndRound(decimal conversion, int denominator)
    {
        this.Increment = conversion / denominator;
        this.Maximum = conversion * Math.Round(MaximumPointSize * denominator / conversion) / denominator;
        this.Value = conversion * Math.Round(this.Value * denominator / conversion) / denominator;
    }

    public decimal MaximumPointSize { get; set; }

    private UnitSystem units;
    public UnitSystem Units
    {
        get { return units; }
        set { if (value != Units) {
                units = value;
                switch (Units)
                {
                    case UnitSystem.Metric:
                        IncrementAndRound(POINTS_PER_CM, 80);
                        break;
                    case UnitSystem.Imperial:
                        IncrementAndRound(POINTS_PER_INCH, 64);
                        break;
                }
            }
        }
    }

    private const decimal POINTS_PER_CM = 28.3464567m;
    private const decimal POINTS_PER_INCH = 72m;

    protected override void UpdateEditText()
    {
        switch (Units)
        {
            case UnitSystem.Metric:
                this.Text = (this.Value / POINTS_PER_CM).ToString("0.00");
                break;
            case UnitSystem.Imperial:
                this.Text = (this.Value / POINTS_PER_INCH).ToString("0.00");
                break;
        }
    }

    protected override void ValidateEditText()
    {
        try {
            decimal value = decimal.Parse(this.Text.Trim());
            switch (Units)
            {
                case UnitSystem.Metric:
                    this.Value = value * POINTS_PER_CM;
                    break;
                case UnitSystem.Imperial:
                    this.Value = value * POINTS_PER_INCH;
                    break;
            } 
        } catch {
            base.ValidateEditText();
        }
    }
}

以上内容并不常用。有时,ValidateEditText()以相对于Units属性更改的错误顺序调用,并且switch语句导致不正确的转换。

如何修复代码实现或我的设计?

1 个答案:

答案 0 :(得分:0)

我会在NumericUpDown中选择数字,而在ComboBox旁边的单位。对于客户来说,它最明显。

MS Word数字上下单元与您的解决方案的工作方式不同。在那里你有只有一个单位(比方说cm)。您可以输入包含任何单位的文本(例如mm),但内部转换为所述单位cm)。在您按向上 向下或关闭窗口(下次打开时,您将看到Text中的值)之前,cm不会更新。

我认为您必须检查TextChanged(不是ValidateEditText,但保持覆盖并且什么也不做),只是在UpdateEditText中设置文本时以不同的方式威胁它。另一件事是动态增量/减量。它可能不适合用户(例如,用户期望值增加0.1忽略单位。)

另外,请检查this

相关问题