键入时未触发 NumericUpDown ValueChanged 事件
NumericUpDown ValueChanged event not firing while typing
我有绑定的 NumericUpDown 控件。
我希望 ValueChanged
事件在单击向上或向下箭头或用户更改数字时触发。
单击向上或向下箭头时,ValueChanged
事件会触发,
但不是当我只是输入控件时。
// numericUpDownDiscountRate
//
this.numericUpDownDiscountRate.DecimalPlaces = 4;
this.numericUpDownDiscountRate.Location = new System.Drawing.Point(133, 344);
this.numericUpDownDiscountRate.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.numericUpDownDiscountRate.Name = "numericUpDownDiscountRate";
this.numericUpDownDiscountRate.Size = new System.Drawing.Size(115, 23);
this.numericUpDownDiscountRate.TabIndex = 78;
this.numericUpDownDiscountRate.ValueChanged += new System.EventHandler(this.numericUpDownDiscountRate_ValueChanged);
我发现了一个建议使用 KeyPress event 的问题
但是,按键事件发生在值更新之前。
如何从按键中获取控件的值?
private void numericUpDownDiscountPercent_KeyPress(object sender, KeyPressEventArgs e)
{
if (loadingForm) return;
try
{
loadingForm = true;
var updn = sender as NumericUpDown;
// updn.value does not include the key press and I don't know how to construct the value
MyCalculateRate(updn?.Value ?? 0);
loadingForm = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Discount rate Key Press");
loadingForm = false;
}
}
这有点“花言巧语”,但是(在 .netfw472 中 - 尚未在 netcore 中尝试过)如果您将事件处理程序绑定到访问值的 KeyUp:
private void numericUpDown1_KeyUp(object sender, KeyEventArgs e)
{
var v = numericUpDown1.Value; //I know it looks useless, but it seems to make ValueChanged fire more often
}
它会导致您的 ValueChanged 在每次按键时触发,并且在 ValueChanged 中访问 .Value
将为您提供当前值..
“但是为什么?!”你可能会问...“我不知道;我从来没有看过..但是 NumericUpDown 不被认为是最可靠的控件..”
由于 Value
仅在验证后更改,这发生在内部编辑控件失去焦点或检索值时验证输入时,我建议引入一个 自定义 值与默认 Value
属性.
一起使用
请注意,当读取值 属性 时,输入不仅经过验证而且文本也是 re-set,因此在编辑时读取 Value
属性变得相当困难,因为插入符号在重置文本时移动。
当按下 Up/Down 按钮时,文本也会被格式化,因此会调用 OnTextChanged()
并设置自定义值。
在此处的自定义控件中实现,但您可以使用标准 NumericUpDown 控件的事件处理程序执行相同的操作。
由于前面解释的原因,请不要阅读 OnValueChanged()
中的 Value
属性。
在编辑文本时使用 CurrentEditValue
。或者改为订阅 CurrentEditValueChanged
事件。
自定义控件是 DataBinding-friendly.
using System.ComponentModel;
using System.Windows.Forms;
[ToolboxItem(true), DesignerCategory("code")]
public class NumericUpDownEx : NumericUpDown {
private static readonly object Event_CurrentEditValueChanged = new object();
private decimal m_CurrentEditValue = 0M;
public NumericUpDownEx() { }
[Bindable(true), Browsable(false), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual decimal CurrentEditValue {
get => m_CurrentEditValue;
internal set {
if (value != m_CurrentEditValue) {
m_CurrentEditValue = value;
OnCurrentEditValueChanged(EventArgs.Empty);
}
}
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
if (decimal.TryParse(Text, out decimal value)) {
CurrentEditValue = value;
OnValueChanged(e);
}
}
public event EventHandler CurrentEditValueChanged {
add {
Events.AddHandler(Event_CurrentEditValueChanged, value);
}
remove {
Events.RemoveHandler(Event_CurrentEditValueChanged, value);
}
}
protected virtual void OnCurrentEditValueChanged(EventArgs e)
{
if (Events[Event_CurrentEditValueChanged] is EventHandler evth) evth(this, e);
}
}
直接 (One-Way) 绑定到 CurrentEditValue
的示例 属性:
[SomeTextBox].DataBindings.Add("Text", numericUpDpwnEx1, "CurrentEditValue", true, DataSourceUpdateMode.OnPropertyChanged);
我有绑定的 NumericUpDown 控件。
我希望 ValueChanged
事件在单击向上或向下箭头或用户更改数字时触发。
单击向上或向下箭头时,ValueChanged
事件会触发,
但不是当我只是输入控件时。
// numericUpDownDiscountRate
//
this.numericUpDownDiscountRate.DecimalPlaces = 4;
this.numericUpDownDiscountRate.Location = new System.Drawing.Point(133, 344);
this.numericUpDownDiscountRate.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.numericUpDownDiscountRate.Name = "numericUpDownDiscountRate";
this.numericUpDownDiscountRate.Size = new System.Drawing.Size(115, 23);
this.numericUpDownDiscountRate.TabIndex = 78;
this.numericUpDownDiscountRate.ValueChanged += new System.EventHandler(this.numericUpDownDiscountRate_ValueChanged);
我发现了一个建议使用 KeyPress event 的问题 但是,按键事件发生在值更新之前。
如何从按键中获取控件的值?
private void numericUpDownDiscountPercent_KeyPress(object sender, KeyPressEventArgs e)
{
if (loadingForm) return;
try
{
loadingForm = true;
var updn = sender as NumericUpDown;
// updn.value does not include the key press and I don't know how to construct the value
MyCalculateRate(updn?.Value ?? 0);
loadingForm = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Discount rate Key Press");
loadingForm = false;
}
}
这有点“花言巧语”,但是(在 .netfw472 中 - 尚未在 netcore 中尝试过)如果您将事件处理程序绑定到访问值的 KeyUp:
private void numericUpDown1_KeyUp(object sender, KeyEventArgs e)
{
var v = numericUpDown1.Value; //I know it looks useless, but it seems to make ValueChanged fire more often
}
它会导致您的 ValueChanged 在每次按键时触发,并且在 ValueChanged 中访问 .Value
将为您提供当前值..
“但是为什么?!”你可能会问...“我不知道;我从来没有看过..但是 NumericUpDown 不被认为是最可靠的控件..”
由于 Value
仅在验证后更改,这发生在内部编辑控件失去焦点或检索值时验证输入时,我建议引入一个 自定义 值与默认 Value
属性.
请注意,当读取值 属性 时,输入不仅经过验证而且文本也是 re-set,因此在编辑时读取 Value
属性变得相当困难,因为插入符号在重置文本时移动。
当按下 Up/Down 按钮时,文本也会被格式化,因此会调用 OnTextChanged()
并设置自定义值。
在此处的自定义控件中实现,但您可以使用标准 NumericUpDown 控件的事件处理程序执行相同的操作。
由于前面解释的原因,请不要阅读 OnValueChanged()
中的 Value
属性。
在编辑文本时使用 CurrentEditValue
。或者改为订阅 CurrentEditValueChanged
事件。
自定义控件是 DataBinding-friendly.
using System.ComponentModel;
using System.Windows.Forms;
[ToolboxItem(true), DesignerCategory("code")]
public class NumericUpDownEx : NumericUpDown {
private static readonly object Event_CurrentEditValueChanged = new object();
private decimal m_CurrentEditValue = 0M;
public NumericUpDownEx() { }
[Bindable(true), Browsable(false), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual decimal CurrentEditValue {
get => m_CurrentEditValue;
internal set {
if (value != m_CurrentEditValue) {
m_CurrentEditValue = value;
OnCurrentEditValueChanged(EventArgs.Empty);
}
}
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
if (decimal.TryParse(Text, out decimal value)) {
CurrentEditValue = value;
OnValueChanged(e);
}
}
public event EventHandler CurrentEditValueChanged {
add {
Events.AddHandler(Event_CurrentEditValueChanged, value);
}
remove {
Events.RemoveHandler(Event_CurrentEditValueChanged, value);
}
}
protected virtual void OnCurrentEditValueChanged(EventArgs e)
{
if (Events[Event_CurrentEditValueChanged] is EventHandler evth) evth(this, e);
}
}
直接 (One-Way) 绑定到 CurrentEditValue
的示例 属性:
[SomeTextBox].DataBindings.Add("Text", numericUpDpwnEx1, "CurrentEditValue", true, DataSourceUpdateMode.OnPropertyChanged);