2010-04-14 3 views
26

ich einen einfachen WPF-Dialog mit diesen beiden Kontrollen habe:WPF MVVM: TextBox und Button-Standard Bindung tut Update zu spät

<TextBox Text="{Binding MyText}"/> 
<Button Command="{Binding MyCommand}" IsDefault="True"/> 

Nun, wenn ich einen Text in dem Textfeld ein und klicken Sie auf die Schaltfläche mit Die Maus funktioniert wie erwartet: Die TextBox setzt MyText und MyCommand wird aufgerufen.

Aber wenn ich einen Text eingeben und drücken Sie die Eingabetaste, um auf die Standardschaltfläche "klicken", es funktioniert nicht. Da beim Klicken auf den Fokus die TextBox nicht verlassen wird, wird die Bindung nicht aktualisiert MyText. Wenn MyCommand aufgerufen wird (was funktioniert), enthält MyText alte Daten.

Wie behebe ich das in MVVM? Im klassischen Code-Behind würde ich wahrscheinlich "MyButton.Focus()" im MyCommand-Handler aufrufen, aber in MVVM weiß der MyCommand-Handler nichts über die Schaltfläche.

Also was jetzt?

Antwort

30

Fügen Sie den UpdateSourceTrigger zu Ihrem TextBox mit dem Wert PropertyChanged hinzu. Das Standardverhalten der Textbox besteht darin, die Quelle zu aktualisieren, wenn sie den Fokus verloren hat.

<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}"/> 
+2

Also müsste ich das zu jeder Bindung hinzufügen (da es immer Schaltflächen gibt, auf die meine Tastaturkürzel zugreifen können)? – Sam

2

Eine Lösung ist es, einen eigenen Class OKButton zu erstellen, der Me.Focus in der OnClick-Methode aufruft. Dies wird vor dem Click_Event und vor jedem Befehl, der an die Schaltfläche gebunden ist, aufgerufen. Sie müssen nur daran denken, einen OKButton anstelle der Einstellung IsDefault = True

+0

Was ist mit Schaltflächen, die nicht die Standardschaltfläche sind und mit ihrer Alt-Verknüpfung aktiviert werden? Dies würde für sie nicht funktionieren. – Sam

5

zu verwenden Versuchen Sie dies. Dieser Code verschiebt den Fokus auf die angeklickte Schaltfläche. Somit wird die Bindung abgeschlossen, bevor der Befehl verarbeitet wird.

public App() 
    { 
     EventManager.RegisterClassHandler(typeof(Button), Button.ClickEvent, new RoutedEventHandler(GenericButtonClickHandler)); 
    } 

    void GenericButtonClickHandler(object sender, RoutedEventArgs e) 
    { 
     var button = sender as Button; 
     if (button == null) 
      return; 
     if (button.IsDefault) 
      button.Focus(); 
    } 
+0

Was ist mit Schaltflächen, die nicht die Standardschaltfläche sind und mit ihrer Alt-Verknüpfung aktiviert werden? Dies würde für sie nicht funktionieren. – Sam

+0

Ja, Sam. Du hast Recht 'if (button.IsDefault)' ist nicht anwendbar für generische Lösung. – Aleks

+0

Aber die Idee dieser Lösung ist, alle Klicks vor der Verarbeitung zu erfassen und den Fokus auf eine Schaltfläche an einem Ort zu setzen. Aber nicht 'UpdateSourceTrigger' in einem bearbeitbaren Steuerelement durch die ganze Anwendung. – Aleks