Autor Beitrag
IsNull
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 97
Erhaltene Danke: 11


VS 2010, C#, AHK
BeitragVerfasst: Di 01.03.11 10:22 
Hallo,

Ich habe eine Applikation entwickelt nach den im Titel genannten Pattern. Um WPF ReDO/Undo Support zu spendieren, sehen die meisten stellen wo Commands exportiert werden in den ViewModels so aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
        /// <summary>
        /// Retruns a Command to Optimize this Routepath
        /// </summary>
        public ICommand OptimizeRoutePathCommand {
            get {
                return new WrapperCommand(new OptimizeRoutePathCommand(_route));
            }
        }

Ich binde also das ICommand in der View, und damit ich meine Liste von Commands führen kann, gibts um meine UnDoCommands ein WrapperCommand, was dann Execute/CanExecute an mein Command weiterleited, und beim Execute mein Command auch in die CommandHistory schreibt (Clone() des Commands).

Mein Problem ist nun folgendes: Irgendwie kann ich nicht genau steuern, wann ein Command neu erstellt wird, und wann lediglich das CanExecute aufgerufen wird. Evtl war das jetzt verwirrend ausgedrückt aber folgendes Fallbeispiel sollte mein Problem aufzeigen:

Ich habe ein Command, was zu der Aktiven Route Selektierte Wegpunkte hinzufügen muss. Ich könnte nun a) im Constructor des Commands jeweils die Aktive Route übergeben, oder b), dem RoutenCommand die möglichkeit geben, selber die Aktive Route ausfindig zu machen.

Ich würde a) bevorzugen, da ich dann das Command viel besser an anderen Orten nutzen kann, aktuell habe ich es aber nach b) gelöst.
Oder ist es generell die Idee, ein Command nur einmal zu instanzieren?

Konkret würde ich mich freuen, wenn jemand der unter WPF das Command Pattern mit Undo/Redo Support implemnetiert hat einige Tipps geben könnte, wie er das gelöst hat. M$ liefert leider nur spärliche Infos - die lösen das immer über RelayCommands (delegates) ohne Undo/Redo Support daher bringt mir das wenig.
IsNull Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 97
Erhaltene Danke: 11


VS 2010, C#, AHK
BeitragVerfasst: Do 03.03.11 14:25 
Ich habe es nun vorübergehen so gelöst:

Mein Command Exportiert ein IsExectued Property sowie einen "Executed" Event.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
AddSelectedDeliverysToARoute _addSelectionToActiveRouteCommand;
static PropertyChangedEventArgs addSelectionToActiveRouteCommandEventArgs = new PropertyChangedEventArgs("AddSelectionToActiveRouteCommand");

public ICommand AddSelectionToActiveRouteCommand {
    get {
        if (_addSelectionToActiveRouteCommand == null || _addSelectionToActiveRouteCommand.IsExecuted) {
            _addSelectionToActiveRouteCommand = new AddSelectedDeliverysToARoute(_selectionService);
            _addSelectionToActiveRouteCommand.Executed += (sender, eventargs) => OnPropertyChangedInvoker(null, addSelectionToActiveRouteCommandEventArgs);
        }
        return new WrapperCommand(_addSelectionToActiveRouteCommand);
    }
}


Der Sinn dabei ist, dass sobald das Command ausgeführt wurde, das CommandProperty selber "AddSelectionToActiveRouteCommand" invalidiert wird, und da dann beim auflösen vom Binding IsExecuted auf true steht, wird ein euer Command erstellt.