首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将命令对象与正确的接收器关联?

如何将命令对象与正确的接收器关联?
EN

Software Engineering用户
提问于 2015-12-22 14:24:43
回答 1查看 455关注 0票数 9

我尝试使用指挥模式在我的项目中实现撤消和重做。

代码语言:javascript
复制
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中的实现。

代码语言:javascript
复制
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";
    }
 }
...

UndoRedo堆栈存储在FormMain类中,并传递给编辑器表单。

代码语言:javascript
复制
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中,用户单击“重做”或“撤消”按钮时,将执行FormEdit中的相应函数,但正如我所检查的,该命令的接收方是第一次创建命令的形式,现在可能已被释放。我希望程序会引发错误,但是Command对象似乎存储了对旧表单的引用,这会导致错误行为。

因此,我认为我必须为命令找到一个一致的接收器,无论是主窗体还是webBrowser控件,它们的生存期与命令本身相同。但是,我应该可以访问与这些命令相关的一些控件。

作为Command对象的接收方,实现命令函数的最佳位置在哪里?或将新窗体与堆栈中弹出的命令关联的任何其他方式。

EN

回答 1

Software Engineering用户

发布于 2016-08-10 16:03:13

命令模式应该应用于模型,而不是UI。在你的情况下,让它

代码语言:javascript
复制
protected HtmlDocument Receiver { set; get; }
protected HtmlElement Element { set; get; }

要更新UI,请使用观察者模式,这样所有打开的表单及其控件都可以对底层模型中的更改做出反应。

您的代码将变得更清晰和更解耦,因为Command只能负责更改文档,UI中的观察者只需要更新控件,而不考虑更改的确切内容。

当表单关闭时,它会将自己注销为观察者,并且不保留对它的引用。

如果在文档更改后打开了一个新表单,则在撤消之后会通知它,即使它在进行原始更改时不存在。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/305644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档