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 AddElement
perintah 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 Undo
dan Redo
tumpukan disimpan dalam FormMain
kelas 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 FormEdit
pengguna baru mengklik tombol Redo atau Undo, fungsi yang sesuai dalam FormEdit
dieksekusi, 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 Command
objek 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 Command
objek? Atau cara lain untuk mengaitkan formulir baru ke perintah yang muncul dari tumpukan.
Receiver
setiap objek perintah, saya akan melakukan ini.