如何检测用户对 WinForms 中的 NumericUpDown 字段所做的更改

本文关键字:字段 NumericUpDown 中的 WinForms 何检测 检测 用户 | 更新日期: 2023-09-27 18:37:21

我的表单上有很多NumericUpDown字段,我希望每当用户编辑其中一个字段时,我都会重新计算所有这些字段。

不用说,我不能只使用ValueChanged事件,因为它也是由程序化更改触发的,这给了我们一个无限循环。

那么,如何区分用户所做的调整和编程属性更改呢?

我需要用户能够以两种方式编辑字段 - 通过单击递增/递减按钮和直接编辑字段文本。

如何检测用户对 WinForms 中的 NumericUpDown 字段所做的更改

如果您不想要全局标志,则始终可以在以编程方式更改值之前暂时取消事件连接:

private void MyMethod()
{
    numericUpDown.ValueChanged -= numericUpDown_ValueChanged;
    numericUpDown.Value = 100;
    numericUpDown.ValueChanged += numericUpDown_ValueChanged;
}
您可以使用

一些带有有关内部字段currentValue的通知的Reflection,并创建自己的NumericUpDown,如下所示:

public class CustomNumericUpDown : NumericUpDown {
    static System.Reflection.FieldInfo currentValue;
    static CustomNumericUpDown() {
        currentValue = typeof(NumericUpDown).GetField("currentValue",
                             System.Reflection.BindingFlags.NonPublic | 
                             System.Reflection.BindingFlags.Instance);
    }
    public CustomNumericUpDown() {
        RaiseValueChangedOnlyByUser = true;
    }
    public bool RaiseValueChangedOnlyByUser { get; set; }
    public new decimal Value {
        get { return base.Value; }
        set
        {
            if (RaiseValueChangedOnlyByUser){
                currentValue.SetValue(this, value);
                UpdateEditText();
            }
            else base.Value = value;
        }
    }
}
//Then in your code just use the `Value` normally, it won't
//never fire the ValueChanged event unless user changes it via the UI
//You can set the RaiseValueChangedOnlyByUser to false to 
//enable firing ValueChanged when the value is changed by code (like as 
//the standard NumericUpDown does)
当以

编程方式更改值时,您可以设置一个标志,然后重新设置它,然后您可以在 Value Changed 事件中检查标志,并在以编程方式设置值时忽略该事件。

没有直接的方法可以判断给定的变体是由用户还是代码引起的。在这些情况下,我通常做的是依靠全局标志。示例代码:

bool autoChanged;
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
    if (!autoChanged)
    {
        //Perform actions you wish when the value is changed by the user
    }
    autoChanged = false;
}
private void button1_Click(object sender, EventArgs e)
{
    autoChanged = true; //Setting the flag to true every time the .Value property is modified via code
    numericUpDown1.Value = 5;
}
  1. 继承 NumericUpDown 类
  2. 为确定以编程方式更改的值或由 GUI 更改的值创建一个标志
  3. 重载值 要在标志上方设置的属性

这是我在VB .NET中的实现。也适用于数据绑定的情况

Private m_blnIsValueChangedByGui As Boolean = True
Public Property IsValueChangedByGui() As Boolean
    Get
        Return m_blnIsValueChangedByGui
    End Get
    Set(ByVal value As Boolean)
        m_blnIsValueChangedByGui = value
    End Set
End Property
Public Shadows Property Value() As Decimal
    Get
        Return MyBase.Value
    End Get
    Set(ByVal value As Decimal)
        IsValueChangedByGui = False
        If (value > Me.Maximum) Then
            MyBase.Value = Me.Maximum
        ElseIf (value < Me.Minimum) Then
            MyBase.Value = Me.Minimum
        Else
            MyBase.Value = value
        End If
        IsValueChangedByGui = True
    End Set
End Property

使用仅在用户从接口更改值时触发的已验证事件处理程序。此事件在 ValueChanged 之后触发,并且在以编程方式更改值时不会触发。