簡體   English   中英

鍵入時未觸發 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 事件的問題,但是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM