2

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

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

那么如何区分用户进行的调整和程序化的属性更改呢?

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

4

6 回答 6

5

如果你不想要一个全局标志,你总是可以在以编程方式更改值之前暂时取消事件:

private void MyMethod()
{
    numericUpDown.ValueChanged -= numericUpDown_ValueChanged;
    numericUpDown.Value = 100;
    numericUpDown.ValueChanged += numericUpDown_ValueChanged;
}
于 2013-10-29T11:11:10.760 回答
3

您可以使用一些Reflection有关内部字段的通知,currentValue并像这样创建自己的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)
于 2013-10-29T13:17:11.560 回答
2

您可以在以编程方式更改值时设置一个标志,然后再将其设置回来,然后您可以检查值已更改事件中的标志,并在以编程方式设置值时忽略该事件。

于 2013-10-29T11:08:19.877 回答
1

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

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;
}
于 2013-10-29T11:07:31.543 回答
1
  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
于 2014-04-03T08:13:25.993 回答
0

使用仅在用户从界面更改值时触发的Validated事件处理程序。此事件在ValueChanged之后触发,并且不会在您以编程方式更改值时触发。

于 2015-09-25T19:56:12.797 回答