简体   繁体   English

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

[英]How can I display different units in a NumericUpDown spin box?

I'm trying to create a control that will allow users to enter a length in a unit of their choice. 我正在尝试创建一个控件,该控件将允许用户以他们选择的单位输入长度。 For the sake of brevity, I'm limiting my code below to centimeters and inches, but in actuality their are more units to choose from than just those two (2). 为了简洁起见,我将我的代码限制为厘米和英寸以下,但实际上它们是可供选择的单位,而不仅仅是这两个(2)。

I thought I could just affect the display of a spinbox with overrides of UpdateEditText() and ValidateEditText() . 我以为我可以通过覆盖UpdateEditText()ValidateEditText()来影响UpdateEditText()的显示。 This is what I came up with: 这是我想出的:

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();
        }
    }
}

The above doesn't work all the time. 上面的方法并非始终有效。 Sometimes, ValidateEditText() is invoked in the wrong order relative to the Units property changing and the switch statement causes an incorrect conversion. 有时,相对于Units属性更改, ValidateEditText()的调用顺序错误,并且switch语句导致错误的转换。

How would I either fix the code implementation or my design? 我将如何修复代码实现或设计?

I'd select numbers in NumericUpDown , while units in ComboBox next to it. 我会在NumericUpDown选择数字,而在ComboBox单位旁边。 Its the most obvious for the customer thing to use. 对于客户而言,这是最显而易见的。

MS Word numeric up-down with units is working differently, than your solution. 与单位对应的MS Word数字上下工作方式与您的解决方案不同。 In there you have only one unit (lets say cm ). 在那里,您只有一个单位 (比如说cm )。 You can enter text with any units (to example, mm ), but it get internally converted to said unit ( cm ). 您可以输入任何单位的文本(例如mm ),但是文本会在内部转换为所述单位cm )。 Text is not updated until you press Up Down or close the window (next time it is opened, you will see value in cm ). 直到您按Up Down或关闭窗口后, Text才会更新(下次打开时,您将看到以cm值)。

I think you have to check for TextChanged (not ValidateEditText , but keep it overriden and doing nothing), just threat it differently when you are setting text in UpdateEditText . 我认为您必须检查TextChanged (不是ValidateEditText ,但要使其被覆盖并且什么也不做),只是在UpdateEditText中设置文本时以不同的方式威胁它。 Another thing is dynamic increment/decrement. 另一件事是动态增量/减量。 It may not work well for the user (to example, user is expecting to have value incremented by 0.1 disregards of units). 对于用户来说,它可能效果不佳(例如,用户期望值增加0.1而不考虑单位)。

Also, check this . 另外,检查

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C# WinForms numericUpDown 控件(去掉旋转框) - C# WinForms numericUpDown control (removing the spin box) 如何将NumericUpDown控件设置为无限? - How can I set the NumericUpDown Control to Infinity? 如何在 WinForms 中同步 NumericUpDown 和 TrackBar 控件的值? - How can I sync the values of NumericUpDown and TrackBar controls in WinForms? 如何根据组合框的选定值,我可以在 numericupdown 中允许值 >= 0? - How depending the selected value of a combobox, i can allow in a numericupdown the value to be >= 0? 如何使用NumericUpDown计算文本框值的总和? - How can I calculate textbox values' total with NumericUpDown? 如何在 C# 的 NumericUpDown 中显示“0000”而不是“0” - How To Display “0000” instead “0” in NumericUpDown in C# 如何以 MB 为单位显示长单位并在进度条中显示进度百分比? - How can i display long units in MB and also displaying percentages progress in a progressBar? WPF绑定/显示不同的单元 - WPF binding/display of different units 如何将文本文件字符串转换为 integer 并在 C# 中的 numericUpDown 中显示 - How do I make a textfile string convert to an integer and display in a numericUpDown in C# 我可以在 NumericUpDown 控件中隐藏值吗? - Can I hide Value in NumericUpDown control?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM