Meine App wird mit dem MVVM-Muster in WPF geschrieben, und alle meine Schaltflächen verwenden Befehlsbindungen, um Code in meinem Modell auszuführen. Alle Befehle verfügen über Code in CanExecute, um den aktivierten Status der gebundenen Schaltfläche zu bestimmen. Die Logik funktioniert einwandfrei, aber in allen Fällen bleibt die GUI in einem deaktivierten Zustand, wenn ich nicht irgendwo anders in der GUI klicke.Seltsames Problem, bei dem die Schaltfläche nicht wieder aktiviert wird, wenn die Maus nicht geklickt wird
Zum Beispiel habe ich eine Schaltfläche mit dem Namen Discard Candy. Wenn ich auf diese Schaltfläche klicke, wird ein Prozess in einem Threadpool-Thread gestartet, der eine Bool-Eigenschaft namens Running auf true setzt. Da die CanExecute Methode für Verwerfen Candy Befehl wird so etwas wie diese
public bool CanExecute(object parameter)
{
return !Running;
}
die Schaltfläche sieht deaktiviert werden, wenn der Prozess beginnt. Das Problem ist, dass wenn der Prozess abgeschlossen ist, wird Running auf false festgelegt, aber die GUI wird nicht aktualisiert, d. H. Discard Candy wird nicht erneut aktiviert.
Wenn ich jedoch irgendwo in der GUI klicke, wie im Fenster oder in der Titelleiste, wird die Schaltfläche Candy verwerfen plötzlich aktiviert. Die Logik funktioniert also, aber etwas passiert, das ich einfach nicht verstehe. Kann mir bitte jemand dieses Verhalten erklären?
EDIT - bis jetzt klingt es wie CommandManager.InvalidateRequerySuggested hat Menschen nicht geholfen. Ich werde es versuchen, aber im Moment bin ich vorsichtig. Ich folgte den empfohlenen Links und entschied mich, mehr über das MVVM Light Toolkit zu lesen. Es klingt sehr schön - hat jemand hier es verwendet und in der Lage zu bestätigen, dass es das Problem, das ich bisher gesehen habe, nicht ausstellen? Obwohl ich plane, das MVVM Light Toolkit in der nächsten großen rev. von meiner Anwendung möchte ich nicht alle Kommandos wiederholen, die ich momentan habe, weshalb ich wahrscheinlich mit CommandManager.InvalidateRequerySuggested beginnen werde, damit wir alle hier einen weiteren Datenpunkt bezüglich seiner Nützlichkeit bekommen können.
EDIT # 2 - sehr interessant, das MVVM Light Toolkit tatsächlich setzt auf CommandManager.InvalidateRequerySuggested um die UI-Fähigkeit zu unterstützen, zu deaktivieren/Befehle wieder aktivieren. Der Autor sagt:
"Streng genommen, in WPF, und wenn Ihr Befehl an ein Steuerelement gebunden ist, das von CommandManager überwacht wird, sollten Sie das Ereignis CanExecuteChanged nicht selbst auslösen müssen. Sie können den CommandManager behandeln lassen Aus diesem Grund können externe Ereignisse auch den Status der Benutzeroberfläche ändern. Stellen Sie sich vor, dass die Benutzeroberfläche von 9 bis 17 Uhr aktiviert und dann für die Nacht deaktiviert werden sollte. Der Benutzer löst die Benutzeroberfläche nicht aus. höflich), dass die Befehlsmanager den Zustand der Befehle erneut abfragt. Dies wird durch den Aufruf die Methode auf der Command InvalidateRequerySuggested getan. Und wie Sie die Methode RaiseCanExecuteChanged der RelayCommand Klasse vermuten, dass nicht nur. "
Können Sie den Code anzeigen, der Running auf false setzt? Ist es im Callback, nachdem der Thread abgeschlossen ist? –
Heben Sie CanExecuteChanged für den Befehl, wenn Sie Running festlegen? – itowlson
@John: Running wird auf "false" gesetzt, nachdem der Workflow abgeschlossen wurde. Dies ist bekannt, wenn das angegebene Ereignis festgelegt wird. @itowlson: Ich hatte den Eindruck, dass alles "nur magisch funktionieren würde". Als ich dieses Zeug lernte, habe ich in CanExecute einen Haltepunkt gesetzt und es wurde immer wieder getroffen ... aber ich stelle mir vor, dass dies nur deshalb der Fall ist, weil die GUI beim Drücken von F5 neu gezeichnet wird und CanExecute dann erneut aufgerufen wird. Wie dumm von mir! – Dave