我正在尝试创建一个控件,允许用户以他们选择的单位输入长度。为了简洁起见,我将下面的代码限制在厘米和英寸范围内,但实际上它们可以选择的单位多于那两个(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语句导致不正确的转换。
如何修复代码实现或我的设计?
答案 0 :(得分:0)
我会在NumericUpDown
中选择数字,而在ComboBox
旁边的单位。对于客户来说,它最明显。
MS Word数字上下单元与您的解决方案的工作方式不同。在那里你有只有一个单位(比方说cm
)。您可以输入包含任何单位的文本(例如mm
),但内部转换为所述单位(cm
)。在您按向上 向下或关闭窗口(下次打开时,您将看到Text
中的值)之前,cm
不会更新。
我认为您必须检查TextChanged
(不是ValidateEditText
,但保持覆盖并且什么也不做),只是在UpdateEditText
中设置文本时以不同的方式威胁它。另一件事是动态增量/减量。它可能不适合用户(例如,用户期望值增加0.1
忽略单位。)
另外,请检查this。