Komut nesnelerini doğru alıcıyla nasıl ilişkilendirebilirim?


9

Projemde Geri Al ve Yinele'yi uygulamak için Komut Deseni kullanmaya çalıştım

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);
    }
}

AddElementKomutun uygulanması 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";
    }
 }
...

Undove Redoyığınlar saklanır FormMainsınıf ve düzenleyici formuna geçirilir.

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;

Yeni bir FormEditkullanıcıda Yeniden Yap veya Geri Al düğmesine tıkladığında, ilgili işlev FormEdityürütülür, ancak komutun bu alıcısını kontrol ettiğimde, komutun ilk oluşturulduğu ve şimdi atılabileceği formdur. Programın bir hata oluşturmasını bekliyorum, ancak Commandnesnenin eski forma başvuru kaydettiği ve bu da hatalı davranışa yol açtığı görülüyor .

Bu nedenle, komutların kendileriyle aynı yaşam süresine sahip olan ana form veya webBrowser denetimi için komutlar için tutarlı bir alıcı bulmam gerektiğini düşünüyorum. Ancak komutlarla ilgili bazı denetimlere erişebilmeliyim.

Komut işlevlerini Commandnesnelerin alıcısı olarak uygulamak için en iyi yer nerede ? Veya yeni formu yığından açılan bir komutla ilişkilendirmenin başka bir yolu.


Bence bu karar senin üstünde. Size yardımcı olamayız çünkü uygulamanızın özelliklerini veya fonksiyonel gereksinimlerini bilmiyoruz.
Euphoric

8
Komut nesneleri yalnızca serileştirilebilir veriler (yani, diğer nesnelere referans yok) içermesi gerektiğine inanıyorum çünkü yaygın kullanımları, serileştirilmiş formlarını ağlar arasında göndermeyi, daha sonra kullanmak üzere bir dosyaya kaydetmeyi veya farklı bir alıcıda yeniden oynatmayı içerir. gerçek zamanlı olarak ekranımda görünecek değişiklikleriniz). Bu, her komut yöntemine Alıcı iletmek istediğiniz anlamına gelebilir veya Alıcı'nın kendisini geçirmesine izin veren executeCommand () / undoCommand () yöntemlerini vermek veya belki kod yerine yalnızca yöntem adlarını / bağımsız değişkenlerini içeren komut nesnelerini kullanmak istediğiniz anlamına gelebilir .
Ixrec


@Ixrec Tavsiyeniz için teşekkür ederiz, o zaman Receiverher komut nesnesini ayarlayabilmem gerektiğini kastediyorum , bunu yapacağım.
Ahmed

Bunun yerine hatıra desenini kullanmayı düşünün.
S. Roe

Yanıtlar:


1

Komut desen için de geçerli olmalıdır modeli değil, UI. Senin durumunda, yap

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

Kullanıcı arayüzünü güncellemek için Gözlemci desenini kullanın , böylece tüm açık formlar ve denetimleri temel alınan modeldeki değişikliklere tepki verebilir.

Komut yalnızca belgeyi değiştirmeye özen gösterebileceğinden ve kullanıcı arayüzündeki gözlemcilerin yalnızca tam olarak neyin değiştiğine bakılmaksızın kontrolleri güncellemeleri gerektiğinden kodunuz daha net ve ayrıştırılmış olacaktır .

Bir form kapandığında, bir gözlemci olarak kaydını siler ve ona hiçbir referans tutulmaz.

Belgede yapılan bir değişiklikten sonra yeni bir form açılırsa, geri alma işleminden sonra orijinal değişiklik yapıldığında mevcut olmasa bile bu form bilgilendirilir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.