Come faccio ad associare oggetti comando con il ricevitore giusto?

9

Ho provato a utilizzare Command Pattern per implementare Annulla e Ripristina nel mio progetto

public abstract class Command
{
    protected Form Receiver { set; get; }
    protected HtmlElement Element { set; get; }
    abstract public void ReDo();
    abstract public void UnDo();
    public Command(Form receiver)
    {
        this.Receiver = receiver;
    }
}
class AddElementCmd : Command
{        
    public AddElementCmd(HtmlElement elem, Form receiver)
        : base(receiver)
    {
        Element = elem;
    }
    public override void ReDo()
    {
        ((FormEdit)Receiver).AddElement(Element,false);
    }
    public override void UnDo()
    {
        ((FormEdit)Receiver).DelElement(Element, false);
    }
}
class DelElementCmd : Command
{
    public DelElementCmd(HtmlElement elem, Form receiver)
        : base(receiver)
    {
        Element = elem;
    }
    public override void ReDo()
    {
        ((FormEdit)Receiver).DelElement(Element, false);
    }
    public override void UnDo()
    {
        ((FormEdit)Receiver).AddElement(Element, false);
    }
}

Implementazione del comando AddElement in FormEdit .

public void AddElement(HtmlElement elem, bool isNew = true)
{
    IHTMLElement2 dom = elem.DomElement as IHTMLElement2;
    if (isNew)
    {
        Command cmd = new AddElementCmd(elem, this);
        Undo.Push(cmd);
        Redo.Clear();
    }    
    // some codes here....
    if (showAlltoolStripButton.Checked)
    {
        dom.runtimeStyle.visibility = "hidden";
    }
    else if (showSelectionToolStripButton.Checked)
    {
        dom.runtimeStyle.visibility = "visible";
    }
 }
...

gli stack Undo e Redo sono memorizzati nella classe FormMain e vengono passati al modulo di editor.

public Stack<Command> Undo = new Stack<Command>();
public Stack<Command> Redo = new Stack<Command>();

....
FormEdit editor = new FormEdit ();
editor.Browser = webBrowser1;
editor.addedElements = addedElements;
editor.restoreElements = restoreElements;
editor.Undo = Undo;
editor.Redo = Redo;

Quando in un nuovo FormEdit l'utente fa clic sul pulsante Ripeti o Annulla, viene eseguita la funzione corrispondente in FormEdit , ma quando ho controllato questo destinatario del comando è la forma in cui il comando è stato creato e ora potrebbe essere stato eliminato. Mi aspetto che il programma generi un errore, ma sembra che l'oggetto Command memorizzi un riferimento al vecchio modulo e questo porti a comportamenti scorretti.

Pertanto, penso di dover trovare un ricevitore coerente per i comandi, sia la forma principale che il controllo webBrowser, che ha la stessa durata dei comandi stessi. Ma ancora dovrei avere accesso ad alcuni controlli relativi ai comandi.

Qual è il posto migliore per implementare le funzioni di comando come destinatario di Command oggetti? O qualsiasi altro modo per associare il nuovo modulo a un comando spuntato dallo stack.

    
posta Ahmad 22.12.2015 - 15:24
fonte

1 risposta

1

Il modello Comando dovrebbe applicarsi al modello e non all'interfaccia utente. Nel tuo caso, fallo

protected HtmlDocument Receiver { set; get; }
protected HtmlElement Element { set; get; }

Per aggiornare l'interfaccia utente, utilizza il pattern Observer , in modo che tutti i moduli aperti e i relativi controlli possano reagire alle modifiche nel modello sottostante.

Il tuo codice diventerà più chiaro e più disaccoppiato perché Comando può occuparsi solo della modifica del documento, e gli osservatori nell'interfaccia utente devono solo aggiornare i controlli senza riguardo esattamente ciò che è cambiato.

Quando un modulo si chiude, si annullerà la registrazione come osservatore e non verrà mantenuto alcun riferimento ad esso.

Se un nuovo modulo viene aperto dopo una modifica al documento, verrà notificato dopo un annullamento anche se non era presente quando è stata apportata la modifica originale.

    
risposta data 10.08.2016 - 18:03
fonte

Leggi altre domande sui tag