2009-03-16 13 views
7

W języku C# zdarzenie Changed dla elementu sterującego (na przykład numericupdown) zostaje wywołane niezależnie od tego, czy wartość została zmieniona bezpośrednio przez użytkownika, czy została zmieniona programowo w wyniku niektórych operacji. inne wydarzenie.Ustalenie, czy zmieniono zdarzenie spowodowane wprowadzeniem przez użytkownika, czy nie.

Czy istnieje sposób ustalenia, czy zdarzenie miało miejsce w wyniku wprowadzenia danych przez użytkownika? Na przykład zarówno ręczna zmiana wartości numericUpDown1, jak i kliknięcie przycisku 1 spowoduje wyświetlenie "wartości zmienionej". Co się stanie, jeśli chcę wyświetlić tylko "zmienioną wartość", jeśli została zmieniona przez kliknięcie strzałki w górę/w dół w kontrolce, a nie w wyniku kliknięcia przycisku 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; 
    } 

Odpowiedz

5

Nie ma dobrego sposobu na zrobienie tego. Możesz znaleźć obejścia dla konkretnych przypadków, np.

  • słuchać MouseDown lub czegoś zamiast valueChanged na rozwijanym menu numerycznym.
  • Ustaw flagę w procedurze obsługi zdarzeń kliknięcia przycisku, która uniemożliwi wyświetlenie okna komunikatu.

    Generalnie powinieneś postarać się uporządkować swój formularz w taki sposób, aby nie miało znaczenia, gdzie zmieniła się wartość.

+0

+1 za pomysł "najlepszej praktyki". Mam ten sam problem - ustawienie jednego efektu pola we wszystkich pozostałych. Dodałem wiele wczesnych wyjść, więc zdarzenia tylko się rozpalają, jeśli podstawowe dane się różnią, a logika się rozplątała. – ojrac

1

Nie, nie ma wbudowanego sposobu zrobić to, co staramy się robić jak kod wyzwolić zdarzenie jest wypalanie gdy zmiany wartości.

5

Można sprawdzić, czy numericUpDown jest ActiveControl. Po ustawieniu wartości numericUpDown podczas kliknięcia przycisku, przycisk 1 powinien być ActiveControl. Kiedy użytkownik zmieni wartość poprzez numericUpDown, numericUpDown powinien być ActiveControl.

if(numericUpDown1 == this.ActiveControl) 
{ 
    MessageBox.Show("value changed"); 
} 
0
  1. Dziedziczenie NumericUpDown Klasa
  2. Utwórz flagę dla określenia wartości zmieniane programowo lub zmieniona przez GUI
  3. przeciążeniem wartości nieruchomości ustawić powyżej flagi

Oto moje rozwiązanie w 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

Jednym z interesujących przypadków jest kontrolka ComboBox, która rozróżnia zmiany w selekcji przez zdarzenie SelectionChangeCommitted, które jest wywoływane tylko wtedy, gdy użytkownik wprowadza zmianę za pośrednictwem interfejsu GUI i zdarzenia SelectedIndexChanged, które jest wywoływane za każdym razem, gdy właściwość SelectedIndex zmienia się . Możesz sprawdzić źródło dla ComboBox i zobaczyć, jak to się robi. Oczywiście nie ma gwarancji, że zasadę można przenieść na inne kontrole.

0

Rozwiązałem ten problem wcześniej. Przyjrzyjmy się sterowaniu NumericUpDown jako przykładowym przykładem.

Najpierw utwórz nową kontrolę (nazwij ją MyNumericUpDown), która dziedziczy z NumericUpDown. Utwórz przesłonięcia dla metod UpButton, DownBut i OnLostFocus. Utwórz również publiczną metodę ustawiania wartości kontrolki programowo. Utwórz typ wyliczeniowy o nazwie "ValueChangedType", który ma 4 różne wartości o nazwie TextEdit, UpButton, DownButton i Programmatic (lub wywołaj je w dowolny sposób). Utwórz także właściwość o nazwie ChangedType typu ValueChangedType. Oto, jak wygląda klasa.

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

Teraz w swojej formie utwórz formant MyNumericUpDown (nazwij go "myNUD"). W procedurze obsługi zdarzenia ValueChanged dla formantu można uzyskać wartość właściwości ChangedType i coś z nią zrobić:

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