查找用于UI的命令模式的示例

时间:2008-08-18 18:31:09

标签: .net design-patterns command

我正在开发一个WinForm .Net应用程序,其基本用户界面包括工具栏按钮,菜单项和按键,它们都启动相同的底层代码。现在,每个事件的事件处理程序调用一个常用的方法来执行该功能。

根据我的阅读,Command design pattern可以处理这种类型的操作,还有自动启用/禁用或选中/取消选中UI元素的额外好处。

我一直在网上寻找一个很好的示例项目,但实际上还没有找到一个。有没有人有一个可以分享的好例子?

5 个答案:

答案 0 :(得分:20)

让我们首先确保我们知道Command模式是什么:

  

命令模式封装了一个请求   作为一个对象并给它一个已知的   公共界面。命令模式   确保每个对象都接收它   拥有命令并提供解耦   发送者和接收者之间。发件人   是一个调用一个对象   操作,接收器是一个对象   接收请求并采取行动   它

这是给你的一个例子。有很多方法可以做到这一点,但我将采用一种基于接口的方法来使代码更易于测试。我不确定你喜欢哪种语言,但我是用C#写的。

首先,创建一个描述命令的界面。

public interface ICommand
{
    void Execute();
}

其次,创建将实现命令接口的命令对象。

public class CutCommand : ICommand
{
    public void Execute()
    {
        // Put code you like to execute when the CutCommand.Execute method is called.
    }
}

第三,我们需要设置我们的调用者或发送者对象。

public class TextOperations
{
    public void Invoke(ICommand command)
    {
        command.Execute();
    }
}

第四,创建将使用调用者/发送者对象的客户端对象。

public class Client
{
    static void Main()
    {
        TextOperations textOperations = new TextOperations();
        textOperation.Invoke(new CutCommand());
    }
}

我希望您可以使用此示例并将其用于您正在使用的应用程序。如果您想进一步澄清,请告诉我。

答案 1 :(得分:2)

你走在正确的轨道上。基本上你会有一个代表文档的模型。您将在CutCommand中使用此模型。您将需要更改CutCommand的构造函数以接受要剪切的信息。然后每次,单击剪切按钮,您调用一个新的CutCommand并在构造函数中传递参数。然后在调用Execute方法时在类中使用这些参数。

答案 2 :(得分:1)

Qt对菜单栏/工具栏项使用命令模式。

QActions是从QMenuItem和QToolbar单独创建的,并且可以分别使用setAction()和addAction()方法将Actions分配给QMenuItem和QToolbar。

http://web.archive.org/web/20100801023349/http://cartan.cas.suffolk.edu/oopdocbook/html/menus.html

http://web.archive.org/web/20100729211835/http://cartan.cas.suffolk.edu/oopdocbook/html/actions.html

答案 3 :(得分:1)

尝试开源,.NET编辑器,如SharpDevelopNotepad++

({自然地] http://c2.com/cgi/wiki?CommandPattern对命令模式的一些讨论可能会有所帮助。

答案 4 :(得分:0)

我无法通过示例链接为您提供帮助,但可以自己提供示例。

1)定义ICommand接口:

public abstract class WinFormCommand : ICommand {

}

2)对具体命令执行ICommand实现,还为它们定义抽象基类:

public interface ICommandInvoker {
  void Invoke(ICommand command);
  void ReDo();
  void UnDo();
}

public interface ICommandDirector {
  void Enable(ICommand);
  void Disable(ICommand);
}

public class WinFormsCommandInvoker : ICommandInvoker, ICommandDirector {

    private readonly Dictionary<ICommand, bool> _commands;
    private readonly Queue<ICommand> _commandsQueue;       
    private readonly IButtonDirector _buttonDirector;

    // you can define additional queue for support of ReDo operation

    public WinFormsCommandInvoker(ICommandsBuilder builder, IButtonDirector buttonDirector) {
      _commands = builder.Build();
      _buttonDirector = buttonDirector;
      _commandsQueue = new Queue<ICommand>();
    } 

    public void Invoke(ICommand command) {
        command.Do();
        __commandsQueue.Enqueue(command);
    }

    public void ReDo() {
      //you can implement this using additional queue
    }

    public void UnDo() {
      var command = __commandsQueue.Dequeue();
      command.Undo();
    }

    public void Enable(ICommand command) {
      _commands.[command] = true;
      _buttonDirector.Enable(command);
    }

    public void Disable(ICommand command) {
      _commands.[command] = false;
      _buttonDirector.Disable(command); 
    }
}

3)创建命令调用程序:

    $validator = $this->validator->make($request->all(), $rules);

4)现在,您可以实现ICommandsBuilder,IButtonDirector并将其他接口(如ICheckBoxDirector)添加到WinFormsCommandInvoker。