In C#, the Changed event for a control (say, a numericupdown) gets fired whether the value was change directly by the user or if it was changed programatically as the result
There is no nice way to do it. You can find workarounds for specific cases, e.g.
listen to MouseDown or something instead of valueChanged on the numeric drop down.
Set a flag in button click event handler that will prohibit the message box from showing.
In general you should try to organize your form in a way that it doesn't matter where the value got changed.
No, there is no built-in way to do what you are trying to do as the code to trigger the event is firing when the value changes.
Here is my solution in 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
I have solved this problem before. Let's take the NumericUpDown control as an illustrative example.
First, create a new control (call it MyNumericUpDown) that inherits from the NumericUpDown. Create overrides for the UpButton, DownButton, and OnLostFocus methods. Also create a public method for setting the value of the control programmatically. Create an enum type called 'ValueChangedType' that has 4 different values called TextEdit, UpButton, DownButton, and Programmatic (or call them whatever you like). Also create a property called ChangedType of type ValueChangedType. Here is what the class looks like.
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;
}
}
Now, in your form, create a MyNumericUpDown control (call it 'myNUD'). In the ValueChanged event handler for the control, you can get the value of the ChangedType property, and do something with it:
private void myNUD_ValueChanged(object sender, EventArgs e)
{
MyNumericUpDown nud = sender as MyNumericUpDown;
var myChangedType = nud.ChangedType;
/* do something */
}
You could check to see if the numericUpDown is the ActiveControl. When you set the value of the numericUpDown during the button click, button1 should be the ActiveControl. When the user changes the value via the numericUpDown, then the numericUpDown should be the ActiveControl.
if(numericUpDown1 == this.ActiveControl)
{
MessageBox.Show("value changed");
}
One interesting case is the ComboBox control, which does differentiate between changes in the selection by the SelectionChangeCommitted event, which is raised only when the user makes a change via the GUI, and the SelectedIndexChanged event, which is raised every time the SelectedIndex property changes. You could examine the source for the ComboBox and see how it's done. Of course, there's no guarantee that the principle will be transferable to other controls.