[英]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 事件的問題,但是 keypress 事件發生在值更新之前。
如何從按鍵中獲取控件的值?
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;
}
}
如果您將事件處理程序綁定到訪問值的 KeyUp,這有點“騙局”但是(在 .netfw472 中 - 尚未在 netcore 中嘗試過):
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
屬性一起使用的自定義值。
請注意,當讀取 Value 屬性時,不僅驗證了輸入,而且還重置了 Text,因此在編輯時讀取Value
屬性變得非常困難,因為在重置 Text 時會移動插入符號。
當按下向上/向下按鈕時,文本也會被格式化,因此調用OnTextChanged()
並設置自定義值。
在此處在自定義控件中實現,但您可以使用標准 NumericUpDown 控件的事件處理程序執行相同操作。
不要閱讀OnValueChanged()
中的Value
屬性,原因前面已經解釋過了。
在編輯文本時使用CurrentEditValue
。 或者改為訂閱CurrentEditValueChanged
事件。
自定義控件是 DataBinding 友好的。
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);
}
}
直接(單向)綁定到CurrentEditValue
屬性的示例:
[SomeTextBox].DataBindings.Add("Text", numericUpDpwnEx1, "CurrentEditValue", true, DataSourceUpdateMode.OnPropertyChanged);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.