更新NumericUpDown控件的值而不引发ValueChanged事件(Winforms)
本文关键字:ValueChanged 事件 Winforms 控件 NumericUpDown 更新 | 更新日期: 2023-09-27 18:03:14
我需要在不引发ValueChanged事件(WinForms, c#)的情况下更新NumericUpDown控件的值。
简单的方法是删除事件处理程序,如:
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(我在表单上尝试过-找到了所有事件处理程序)。
您是否尝试过更改内部值并更新文本?这样你就可以绕过被触发的事件处理程序。
如果你看一下源代码(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();
}
}
这还没有经过测试,但我很确定它会工作。:)编码快乐!