确定是否从用户输入发生更改事件

在C#中,控件的Changed事件(例如,numericupdown)会被触发,无论该值是由用户直接更改还是由于某些其他事件而以编程方式更改。

有没有办法确定事件是否是由于用户输入而发生的? 例如,手动更改numericUpDown1的值并单击button1将显示“value changed”。 如果通过用户单击控件中的向上/向下箭头而不是单击button1的结果更改了“值已更改”,该怎么办?

private void numericUpDown1_ValueChanged(object sender, EventArgs e) { MessageBox.Show("value changed"); } private void button1_Click_1(object sender, EventArgs e) { numericUpDown1.Value = 3; } 

没有好办法做到这一点。 您可以找到特定情况的变通方法,例如

  • 在数字下拉列表中监听MouseDown或其他内容而不是valueChanged。
  • 在按钮单击事件处理程序中设置一个标志,该标志将禁止显示消息框。

    一般来说,您应该尝试以一种方式来组织您的表单,使得值的变化无关紧要。

您可以检查numericUpDown是否为ActiveControl。 在按钮单击期间设置numericUpDown的值时,button1应该是ActiveControl。 当用户通过numericUpDown更改值时,numericUpDown应该是ActiveControl。

 if(numericUpDown1 == this.ActiveControl) { MessageBox.Show("value changed"); } 

不,没有内置方法可以执行您要执行的操作,因为触发事件的代码在值更改时触发。

  1. inheritanceNumericUpDown类
  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 

一个有趣的案例是ComboBox控件,它通过SelectionChangeCommitted事件区分选择的更改,该事件仅在用户通过GUI进行更改时引发,而SelectedIndexChanged事件在每次SelectedIndex属性更改时引发。 您可以检查ComboBox的源代码并查看它是如何完成的。 当然,不能保证该原则可以转移到其他控制。

我以前解决了这个问题。 我们以NumericUpDown控件为例进行说明。

首先,创建一个inheritance自NumericUpDown的新控件(称为MyNumericUpDown)。 为UpButton,DownButton和OnLostFocus方法创建替代。 还要创建一个公共方法,以编程方式设置控件的值。 创建一个名为“ValueChangedType”的枚举类型,它有4个不同的值,分别称为TextEdit,UpButton,DownButton和Programmatic(或者随意调用它们)。 还要创建一个名为ValueChangedType类型的ChangedType的属性。 这是class级的样子。

 public partial class MyNumericUpDown : NumericUpDown { public enum ValueChangedType { TextEdit, UpButton, DownButton, Programmatic } public ValueChangedType ChangedType = ValueChangedType.Programmatic; public MyNumericUpDown() { InitializeComponent(); } public override void UpButton() { this.ChangedType = ValueChangedType.UpButton; base.UpButton(); } public override void DownButton() { this.ChangedType = ValueChangedType.DownButton; base.DownButton(); } protected override void OnLostFocus(EventArgs e) { this.ChangedType = ValueChangedType.TextEdit; base.OnLostFocus(e); } public void SetValue(decimal val) { this.ChangedType = ValueChangedType.Programmatic; this.Value = val; } } 

现在,在您的表单中,创建一个MyNumericUpDown控件(称之为’myNUD’)。 在控件的ValueChanged事件处理程序中,您可以获取ChangedType属性的值,并对其执行某些操作:

  private void myNUD_ValueChanged(object sender, EventArgs e) { MyNumericUpDown nud = sender as MyNumericUpDown; var myChangedType = nud.ChangedType; /* do something */ }