2008-09-11 13 views
9

Ich folge dem M-V-VM Muster für meine WPF UI. Ich möchte einen Befehl an das TextChanged-Ereignis einer TextBox an einen Befehl in meiner ViewModel-Klasse anschließen. Die einzige Möglichkeit, die ich mir vorstellen kann, ist das Erben des TextBox-Steuerelements und das Implementieren von ICommandSource. Ich kann dann den Befehl anweisen, vom TextChanged-Ereignis ausgelöst zu werden. Dies scheint zu viel Arbeit für etwas zu sein, das so einfach zu sein scheint.TextBox.TextChanged & ICommandSource

Gibt es einen einfacheren Weg (als die Unterklasse der TextBox und die Implementierung von ICommandSource), um das TextChanged-Ereignis mit meiner ViewModel-Klasse zu verbinden?

Antwort

18

Als Erstes haben Sie sicherlich eine bidirektionale Datenbindung an Ihr Viewmodel mit einem UpdateSourceTrigger von PropertyChanged in Betracht gezogen? Auf diese Weise wird der Eigenschaftensetzer der Eigenschaft, an die Sie binden, jedes Mal aufgerufen, wenn der Text geändert wird.

Wenn das nicht genug ist, würde ich dieses Problem mit Attached Behaviors angehen. Auf Julian Dominguez Blog finden Sie eine article über etwas Ähnliches in Silverlight, die leicht an WPF angepasst werden können.

Grundsätzlich definieren Sie in einer statischen Klasse (z. B. TextBoxBehaviours) eine Attached-Eigenschaft namens (vielleicht) TextChangedCommand vom Typ ICommand. Schließen Sie einen OnPropertyChanged-Handler für diese Eigenschaft an, und überprüfen Sie im Handler, ob die Eigenschaft für eine TextBox festgelegt ist. Wenn dies der Fall ist, fügen Sie dem TextChanged-Ereignis im Textfeld, das den in der Eigenschaft angegebenen Befehl aufruft, einen Handler hinzu.

Dann vorausgesetzt, Ihr Viewmodel hat die Datacontext Ihrer Ansicht zugewiesen wurde, möchten Sie es verwenden:

<TextBox 
    x:Name="MyTextBox" 
    TextBoxBehaviours.TextChangedCommand="{Binding ViewModelTextChangedCommand}" /> 
+1

Dank Sam - manchmal scheitere ich die einfachen Optionen zu sehen; In diesem Fall wurde das Textfeld an eine Zeichenfolgeneigenschaft in meinem ViewModel gebunden. –

+0

Ich glaube nicht, dass das Hinzufügen von Logik zum Setter der Eigenschaft funktionieren würde. Der WPF XAML-Prozessor verwendet die Abhängigkeitseigenschaft direkt und nicht den Eigenschaftenwrapper. Dies bedeutet, dass der Setter nie aufgerufen wird, wenn die Benutzeroberfläche aktualisiert wird. (Quelle: http://msdn.microsoft.com/en-us/library/bb613563.aspx) – Greg

+2

Greg, ich verweise auf den Setter der Eigenschaft im ViewModel, an die die Abhängigkeitseigenschaft gebunden ist, nicht an den Setter der Abhängigkeitseigenschaft selbst. –

3

Können Sie nicht einfach das TextChanged-Ereignis behandeln und den Befehl von dort ausführen?

private void _textBox_TextChanged(object sender, EventArgs e) 
{ 
    MyCommand.Execute(null); 
} 

Die Alternative, wie Sie sagen, ist ein TextBox, die als Befehlsquelle wirkt zu erstellen, aber das übertrieben scheint, es sei denn, es ist etwas bist du auf den Austausch der Planung und an vielen Orten nutzen.

8

Mit der Ereignisbindung und Befehlsmethode möglicherweise nicht das Richtige zu verwenden. Was genau wird dieser Befehl tun?

Möglicherweise möchten Sie eine Datenbindung zu einem Zeichenfolgenfeld in Ihrer VM verwenden. Auf diese Weise können Sie von dort aus einen Befehl oder eine Funktion aufrufen, ohne dass die Benutzerschnittstelle dafür zuständig ist.

<TextBox Text="{Binding WorldName}"/> 
.... 
public string WorldName 
{ 
    get 
    { 
     return WorldData.Name; 
    } 
    set 
    { 
     WorldData.Name = value; 
     OnPropertyChanged("WorldName"); 
     // CallYourCustomFunctionHere(); 
    } 
} 
+0

Danke Nidonocu. Ihre Antwort ist auch perfekt, aber ich habe Sams Antwort als Antwort markiert, weil er leicht vor Ihrer Antwort geantwortet hat. Danke nochmal! –