J'ai essayé d'utiliser le modèle de commande pour implémenter Annuler et Rétablir dans mon projet
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);
}
}
Implémentation du AddElement
commandement en 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";
}
}
...
les piles Undo
et Redo
sont stockées dans la FormMain
classe et transmises au formulaire de l'éditeur.
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;
Quand dans un nouveau FormEdit
l'utilisateur clique sur le bouton Rétablir ou Annuler, la fonction correspondante dans le FormEdit
est exécutée, mais comme j'ai vérifié ce récepteur de la commande est la forme sous laquelle la commande a été créée pour la première fois et peut maintenant être supprimée. Je m'attends à ce que le programme génère une erreur, mais il semble que l' Command
objet stocke une référence à l'ancien formulaire et cela conduit à un mauvais comportement.
Par conséquent, je pense que je dois trouver un récepteur cohérent pour les commandes, soit le formulaire principal, soit le contrôle webBrowser, qui a la même durée de vie que les commandes elles-mêmes. Mais pourtant, je devrais avoir accès à certains contrôles liés aux commandes.
Où est le meilleur endroit pour implémenter les fonctions de commande en tant que récepteur d' Command
objets? Ou toute autre façon d'associer le nouveau formulaire à une commande sortie de la pile.
la source
Receiver
de chaque objet de commande, je vais le faire.Réponses:
Le modèle de commande doit s'appliquer au modèle et non à l'interface utilisateur. Dans votre cas, faites-le
Pour mettre à jour l'interface utilisateur, utilisez le modèle Observer , afin que tous les formulaires ouverts et leurs contrôles puissent réagir aux modifications du modèle sous-jacent.
Votre code deviendra plus clair et plus découplé car Command ne peut prendre en charge que la modification du document, et les observateurs dans l'interface utilisateur n'ont qu'à mettre à jour les contrôles sans tenir compte exactement de ce qui a changé.
Lorsqu'un formulaire se ferme, il se désenregistrera en tant qu'observateur et aucune référence ne sera conservée.
Si un nouveau formulaire est ouvert après une modification du document, il sera notifié après une annulation même s'il n'était pas présent lors de la modification d'origine.
la source