2009-07-31 16 views
7

Ich bin sehr neu zu .Net und WPF und habe ein Problem. Der Code ist ein Snippet. Ich habe TextBox es, um Daten einzugeben. Ich überprüfe die korrekte Eingabe mit den Ereignissen GotFocus und LostFocus.WPF TextBox.Focus() Ärger

<TextBox Name="sdDay" Width="40" Text="Day" GotFocus="DateDay_GotFocus" LostFocus="DateDay_LostFocus" Padding="5,5,5,5" HorizontalContentAlignment="Center" Focusable="True"/> 
<TextBox Name="sdMonth" Width="50" Text="Month" GotFocus="DateMonth_GotFocus" LostFocus="DateMonth_LostFocus" Padding="5,5,5,5" Margin="5,0,0,0" HorizontalContentAlignment="Center" Focusable="True"/> 
<TextBox Name="sdYear" Width="50" Text="Year" GotFocus="DateYear_GotFocus" LostFocus="DateYear_LostFocus" Padding="5,5,5,5" Margin="5,0,0,0" HorizontalContentAlignment="Center" Focusable="True"/> 

Und der Code:

private void DateDay_GotFocus(object sender, RoutedEventArgs e) 
    { 
     if (((TextBox)sender).Text == "Day") 
      ((TextBox)sender).Text = string.Empty; 
    } 

private void DateDay_LostFocus(object sender, RoutedEventArgs e) 
    { 
     if (((TextBox)sender).Text == string.Empty) 
      ((TextBox)sender).Text = "Day"; 
     else 
      CheckForCorrectDateDay((TextBox)sender); 
    } 

private void CheckForCorrectDateDay(TextBox b) 
    { 
     int day = 0; 

     try 
     { 
      day = int.Parse(b.Text); 

      if (day < 0 || day > 31) 
      { 
       MessageBox.Show("Please enter a correct day."); 
       b.Text = string.Empty; 
       b.Focus(); 
      } 
     } 
     catch (FormatException) 
     { 
      MessageBox.Show("Please enter a number.", "Incorrect Input", MessageBoxButton.OK, MessageBoxImage.Warning); 
      b.Text = string.Empty; 
      b.Focus(); 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 

Nun, was ich es für eine korrekte Eingabe Check tun will, und wenn das, auf den Fokus nicht zurück, was auch immer TextBox einen falschen Eintrag hatte.

Es funktioniert aber nicht. Nachdem ich eine Zahl außerhalb des Bereichs (oder Buchstabens) eingegeben habe, wird MessageBox angezeigt, aber der Fokus wechselt zur nächsten TextBox, die für die Eingabe des Monats verwendet wird.

Was mache ich falsch?

Antwort

14

Ihre Technik zur Validierung ist hier, um ehrlich zu sein, sehr schlecht. Das heißt, ich glaube, das Problem ist nur, dass WPF die Registerkarte behandelt, nachdem Sie den Fokus festgelegt haben, sodass der Fokus auf das nächste Element in der Fokusreihenfolge zurückgesetzt wird.

Eine einfache Abhilfe wäre eine separate Nachricht versenden, die nach der aktuellen Nachricht verarbeitet wird:

if (day < 0 || day > 31) 
{ 
    MessageBox.Show("Please enter a correct day."); 
    b.Text = string.Empty; 

    Dispatcher.BeginInvoke((ThreadStart)delegate 
    { 
     b.Focus(); 
    }); 
} 

Dadurch wird sichergestellt, dass WPF die LostFocus Event-Handler vollständig verarbeitet, bevor es die separate Meldung auf das Wesentliche konzentrieren zu setzen Prozesse die fehlerhafte Kontrolle.

Im Hinblick darauf, wie Sie dieses Problem in einer viel schönen Art und Weise angehen könnten, könnten Sie:

  1. einen Blick Modell für Tag, Monat mit Eigenschaften definieren und Jahr (Voraussetzung: auf dem MVVM Muster lesen,)
  2. IDataErrorInfo auf der Ansicht Modell implementieren,
  3. Bind die TextBox es in der Benutzeroberfläche zu den entsprechenden Eigenschaften für die Sicht-Modell (Voraussetzung: lesen auf WPF Daten up-Bindung)
+0

Danke für die Antwort. Ich verstehe Ihre Erklärung des Problems, aber nicht genau, was die Lösung tut. Wie ich schon sagte, ich bin sehr neu in .Net. Und ich hätte nichts gegen einige Tipps zu besseren Validierungstechniken. – Moss

+0

Sicher Sache. Mein Beitrag wurde um einige Details erweitert. –

+0

Ich möchte Kents Kommentar wiederholen - das Zurücksetzen des Fokus ist ein sicherer Weg, um Ihre Benutzer wütend zu machen. –