[英]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
而不考虑单位)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.