2009-03-16 10 views
7

En C#, el evento cambiado para un control (por ejemplo, una actualización numérica) se activa si el usuario cambió el valor directamente o si se cambió programáticamente como resultado de algún otro evento.Determinar si el evento modificado se produjo a partir de la entrada del usuario o no

¿Hay alguna manera de determinar si el evento ocurrió como resultado de la entrada del usuario? Por ejemplo, tanto el cambio manual del valor de numericUpDown1 como el de hacer clic en el botón 1 mostrarán "value changed". ¿Qué ocurre si solo deseo mostrar el "valor cambiado" si se modificó haciendo que el usuario haga clic en las flechas arriba/abajo del control y no como resultado de hacer clic en el botón 1?

private void numericUpDown1_ValueChanged(object sender, EventArgs e) 
    { 
     MessageBox.Show("value changed"); 
    } 

    private void button1_Click_1(object sender, EventArgs e) 
    { 
     numericUpDown1.Value = 3; 
    } 

Respuesta

5

No hay una buena manera de hacerlo. Puede encontrar soluciones para casos específicos, p.

  • escuchar MouseDown o algo en lugar de valueChanged en la caída numérica hacia abajo.
  • Establezca un indicador en el botón haga clic en el controlador de eventos que prohibirá que se muestre el cuadro de mensaje.

    En general, debe intentar organizar su formulario de forma que no importe dónde se modificó el valor.

+0

+1 para la 'mejor práctica' idea. Estoy teniendo el mismo problema: configurar un campo afecta a todos los demás. Agregué muchas salidas tempranas para que los eventos solo se disparen si los datos subyacentes difieren, y la lógica se desenreda. – ojrac

1

No, no hay manera integrada para hacer lo que usted está tratando de hacer que el código para activar el evento está disparando cuando cambia el valor.

5

Puede comprobar para ver si el numericUpDown es ActiveControl. Cuando establece el valor de numericUpDown durante el clic del botón, el botón 1 debe ser ActiveControl. Cuando el usuario cambia el valor a través de numericUpDown, entonces numericUpDown debe ser ActiveControl.

if(numericUpDown1 == this.ActiveControl) 
{ 
    MessageBox.Show("value changed"); 
} 
0
  1. Heredar NumericUpDown Clase
  2. Crear una bandera para determinar el valor cambia mediante programación, o se cambia por GUI
  3. sobrecarga Valor de propiedades para establecer por encima de la bandera

Aquí está mi solución en 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 
0

Un caso interesante es el control ComboBox, que diferencia entre cambios en la selección mediante el evento SelectionChangeCommitted, que se produce solo cuando el usuario realiza un cambio a través de la GUI, y el evento SelectedIndexChanged, que se genera cada vez que cambia la propiedad SelectedIndex . Puede examinar la fuente del ComboBox y ver cómo se hace. Por supuesto, no hay garantía de que el principio sea transferible a otros controles.

0

He resuelto este problema antes. Tomemos el control NumericUpDown como un ejemplo ilustrativo.

Primero, cree un nuevo control (llámelo MyNumericUpDown) que hereda de NumericUpDown. Crear anulaciones para los métodos UpButton, DownButton y OnLostFocus. Cree también un método público para establecer el valor del control mediante programación. Cree un tipo de enumeración llamado 'ValueChangedType' que tenga 4 valores diferentes llamados TextEdit, UpButton, DownButton y Programmatic (o llámelos como desee). También crea una propiedad llamada ChangedType de tipo ValueChangedType. Así es como se ve la clase.

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; 
    } 
} 

Ahora, en su forma, crear un control MyNumericUpDown (llamarlo 'myNUD'). En el controlador de eventos ValueChanged para el control, se puede obtener el valor de la propiedad ChangedType, y hacer algo con él:

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