मैं सही रिसीवर के साथ कमांड ऑब्जेक्ट को कैसे जोड़ूं?


9

मैंने अपने प्रोजेक्ट में Undo और Redo को लागू करने के लिए कमांड पैटर्न का उपयोग करने की कोशिश की

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

में AddElementकमांड का कार्यान्वयन 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";
    }
 }
...

Undoऔर Redoढेर में जमा हो जाती FormMainवर्ग और संपादक फार्म के लिए पारित कर रहे हैं।

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;

जब कोई नया FormEditउपयोगकर्ता Redo या पूर्ववत करें बटन पर क्लिक करता है, तो संबंधित फ़ंक्शन FormEditको निष्पादित किया जाता है, लेकिन जैसा कि मैंने जांचा था कि कमांड का यह रिसीवर वह रूप है जिसमें कमांड पहले बनाया गया था और अब इसका निपटान किया जा सकता है। मुझे उम्मीद है कि कार्यक्रम एक त्रुटि बढ़ाता है, लेकिन ऐसा लगता है कि Commandऑब्जेक्ट पुराने रूप के संदर्भ को संग्रहीत करता है और इससे दुर्व्यवहार होता है।

इसलिए, मुझे लगता है कि मुझे कमांड के लिए एक सुसंगत रिसीवर खोजना होगा, या तो मुख्य रूप या वेबब्रोज़र नियंत्रण, जिसमें कमांड के रूप में एक ही जीवन समय हो। लेकिन फिर भी मुझे कमांड से संबंधित कुछ नियंत्रणों तक पहुंच होनी चाहिए।

Commandऑब्जेक्ट के रिसीवर के रूप में कमांड फ़ंक्शन को लागू करने के लिए सबसे अच्छी जगह कहां है ? या नए फॉर्म को कमांड से जोड़ने के लिए किसी अन्य तरीके से स्टैक से पॉपअप किया जाता है।


मुझे लगता है कि यह निर्णय आप पर है। हम आपकी मदद नहीं कर सकते क्योंकि हम आपके आवेदन के विनिर्देश या कार्यात्मक आवश्यकताओं को नहीं जानते हैं।
व्योम

8
मेरा मानना ​​है कि कमांड ऑब्जेक्ट में केवल क्रमिक डेटा होना चाहिए (अर्थात, अन्य ऑब्जेक्ट का कोई संदर्भ नहीं) क्योंकि उनके लिए सामान्य उपयोगों में नेटवर्क में उनके क्रमबद्ध रूपों को भेजना, उन्हें बाद के लिए फ़ाइल में सहेजना, या उन्हें एक अलग रिसीवर पर फिर से खेलना शामिल है (यदि आप चाहते हैं उदाहरण के लिए, वास्तविक समय में मेरी स्क्रीन पर दिखाने के लिए आपके परिवर्तन)। इसका मतलब यह हो सकता है कि आप प्राप्तकर्ता को प्रत्येक कमांड विधि में पास करना चाहते हैं, या हो सकता है कि रिसीवर को निष्पादित करें () / undoCommand () के तरीके जो इसे स्वयं में पास करते हैं, या हो सकता है कि कमांड ऑब्जेक्ट का उपयोग करें जिसमें कोड के बजाय केवल विधि के नाम / तर्क होते हैं। ।
Ixrec


@Ixrec आपकी सलाह के लिए धन्यवाद, तो आपका मतलब है कि मुझे Receiverप्रत्येक कमांड ऑब्जेक्ट को सेट करने में सक्षम होना चाहिए , मैं यह करने जा रहा हूं।
अहमद

इसके बजाय स्मृति चिन्ह पैटर्न का उपयोग करने पर विचार करें।
पी। रो।

जवाबों:


1

कमान पैटर्न के लिए आवेदन करना चाहिए मॉडल , और नहीं यूआई। अपने मामले में, इसे बनाओ

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

UI को अपडेट करने के लिए, ऑब्जर्वर पैटर्न का उपयोग करें , इसलिए सभी खुले रूप और उनके नियंत्रण अंतर्निहित मॉडल में परिवर्तन पर प्रतिक्रिया कर सकते हैं।

आपका कोड स्पष्ट और अधिक डिकॉउन्ड हो जाएगा क्योंकि कमांड केवल दस्तावेज़ को बदलने का ध्यान रख सकता है, और UI में पर्यवेक्षकों को केवल नियंत्रण में अपडेट करना होगा कि वास्तव में क्या बदल गया है।

जब कोई प्रपत्र बंद हो जाता है, तो वह खुद को एक पर्यवेक्षक के रूप में अपंजीकृत करेगा, और इसका कोई संदर्भ नहीं रखा जाएगा।

यदि दस्तावेज़ में बदलाव के बाद एक नया फॉर्म खोला जाता है, तो यह पूर्ववत होने के बाद भी अधिसूचित किया जाएगा, भले ही यह मूल परिवर्तन किए जाने पर मौजूद न हो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.