Próbowałem użyć Wzorca poleceń do implementacji Cofnij i Ponów w moim projekcie
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);
}
}
Realizacja AddElementpolecenia w 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";
}
}
...
Undoi Redostosy są przechowywane w FormMainklasie i są przekazywane do formularza edytora.
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;
Gdy w nowym FormEditużytkownik kliknie przycisk Ponów lub Cofnij, odpowiednia funkcja w FormEditjest wykonywana, ale jak sprawdziłem, odbiornik polecenia jest formą, w której polecenie zostało utworzone po raz pierwszy, a teraz mogło zostać usunięte. Oczekuję, że program zgłosi błąd, ale wygląda na to, że Commandobiekt przechowuje odniesienie do starej formy, co prowadzi do złego zachowania.
Dlatego myślę, że muszę znaleźć spójny odbiornik dla poleceń, zarówno głównej, jak i kontrolki webBrowser, która ma taki sam czas życia jak same polecenia. Ale powinienem mieć dostęp do niektórych elementów sterujących związanych z poleceniami.
Gdzie jest najlepsze miejsce na wdrożenie funkcji poleceń jako odbiornika Commandobiektów? Lub w jakikolwiek inny sposób powiązania nowego formularza z poleceniem wyskakującym ze stosu.
Receiverkażdy obiekt polecenia, zamierzam to zrobić.