Saya mencoba menggunakan Pola Perintah untuk menerapkan Batalkan dan Kembalikan dalam proyek saya
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);
}
}
Implementasi AddElementperintah di 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";
}
}
...
yang Undodan Redotumpukan disimpan dalam FormMainkelas dan diteruskan ke bentuk redaksi.
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;
Ketika di FormEditpengguna baru mengklik tombol Redo atau Undo, fungsi yang sesuai dalam FormEditdieksekusi, tetapi ketika saya memeriksa penerima perintah ini adalah bentuk di mana perintah pertama kali dibuat dan sekarang mungkin telah dibuang. Saya berharap bahwa program menimbulkan kesalahan, tetapi tampaknya Commandobjek menyimpan referensi ke bentuk lama dan ini mengarah pada perilaku buruk.
Oleh karena itu, saya pikir saya harus menemukan penerima yang konsisten untuk perintah, baik bentuk utama atau kontrol webBrowser, yang memiliki waktu hidup yang sama dengan perintah itu sendiri. Namun saya harus memiliki akses ke beberapa kontrol yang terkait dengan perintah.
Di mana tempat terbaik untuk mengimplementasikan fungsi perintah sebagai penerima Commandobjek? Atau cara lain untuk mengaitkan formulir baru ke perintah yang muncul dari tumpukan.
Receiversetiap objek perintah, saya akan melakukan ini.