如何检测用户对 WinForms 中的 NumericUpDown 字段所做的更改
本文关键字:字段 NumericUpDown 中的 WinForms 何检测 检测 用户 | 更新日期: 2023-09-27 18:37:21
我的表单上有很多NumericUpDown
字段,我希望每当用户编辑其中一个字段时,我都会重新计算所有这些字段。
不用说,我不能只使用ValueChanged
事件,因为它也是由程序化更改触发的,这给了我们一个无限循环。
那么,如何区分用户所做的调整和编程属性更改呢?
我需要用户能够以两种方式编辑字段 - 通过单击递增/递减按钮和直接编辑字段文本。
如果您不想要全局标志,则始终可以在以编程方式更改值之前暂时取消事件连接:
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;
}
- 继承 NumericUpDown 类
- 为确定以编程方式更改的值或由 GUI 更改的值创建一个标志
- 重载值 要在标志上方设置的属性
这是我在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 之后触发,并且在以编程方式更改值时不会触发。