簡體   English   中英

更新NumericUpDown控件的值,而不會引發ValueChanged事件(Winforms)

[英]Update Value of the NumericUpDown control without raising of ValueChanged event (Winforms)

我需要在不引發ValueChanged事件(WinForms,C#)的情況下更新NumericUpDown控件的Value。
簡單的方法是刪除事件處理程序,例如:

numericUpDown.ValueChanged -= numericUpDown_ValueChanged;

之后設置所需的值:

numericUpDown.Value = 15;

並再次添加事件處理程序:

numericUpDown.ValueChanged += numericUpDown_ValueChanged;

問題是我想編寫一種方法,該方法將把NumericUpDown控件作為第一個參數,將所需的值作為第二個參數,並將以下面給出的方式更新該值。
為此,我需要為ValueChanged事件找到連接的事件處理程序(對於每個NumericUpDown來說都是不同的)。
我進行了很多搜索,但沒有找到適合我的解決方案。
我的最后嘗試是:

private void NumericUpDownSetValueWithoutValueChangedEvent(NumericUpDown control, decimal value)
{
    EventHandlerList events = (EventHandlerList)typeof(Component).GetField("events", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).GetValue(control);
    object current = events.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField)[0].GetValue(events);
    List<Delegate> delegates = new List<Delegate>();
    while (current != null)
    {
         delegates.Add((Delegate)GetField(current, "handler"));
         current = GetField(current, "next");
    }
    foreach (Delegate d in delegates)
    {
         Debug.WriteLine(d.ToString());
    }
}
public static object GetField(object listItem, string fieldName)
{
    return listItem.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).GetValue(listItem);
}

在運行NumericUpDownSetValueWithoutValueChangedEvent函數之后, object current等於null,因此未找到一個EventHandler(我在Form上嘗試了它-找到了所有事件處理程序)。

您是否嘗試過僅更改內部值並更新文本? 這樣,您可以繞過被觸發的事件處理程序。

如果您查看源代碼( http://referencesource.microsoft.com/System.Windows.Forms/winforms/Managed/System/WinForms/NumericUpDown.cs.html#0aaedcc47a6cf725 ),您將看到屬性Value為使用名為currentValue的私有字段,這是您要設置的值。 然后只需執行control.Text = value.ToString();

private void SetNumericUpDownValue(NumericUpDown control, decimal value)
{
    if (control == null) throw new ArgumentNullException(nameof(control));
    var currentValueField = control.GetType().GetField("currentValue", BindingFlags.Instance | BindingFlags.NonPublic);
    if (currentValueField != null)
    {
        currentValueField.SetValue(control, value);
        control.Text = value.ToString();
    }
}

這還沒有經過測試,但是我很確定它會起作用。 :)編碼愉快!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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