【问题标题】:Looking for example of Command pattern for UI [closed]寻找 UI 的命令模式示例 [关闭]
【发布时间】:2010-09-06 02:45:48
【问题描述】:

我正在开发一个带有基本 UI 的 WinForm .Net 应用程序,其中包括启动相同底层代码的工具栏按钮、菜单项和击键。现在,每个事件的事件处理程序调用一个通用方法来执行该功能。

据我所知,Command design pattern 可以处理此类操作,并具有自动启用/禁用或选中/取消选中 UI 元素的额外好处。

我一直在网上搜索一个好的示例项目,但真的没有找到。谁有可以分享的好例子?

【问题讨论】:

    标签: .net design-patterns command


    【解决方案1】:

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

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

    这里有一个例子。有很多方法可以做到这一点,但我将采用基于接口的方法来使代码更易于测试。我不确定您喜欢哪种语言,但我是用 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());
        }
    }
    

    我希望你能把这个例子应用到你正在开发的应用程序中。如果您想了解更多信息,请告诉我。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        尝试使用开源的 .NET 编辑器,例如 SharpDevelopNotepad++

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

        【讨论】:

          【解决方案4】:

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

          QActions 与QMenuItem 和QToolbar 分开创建,Actions 可以分别通过setAction() 和addAction() 方法分配给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

          【讨论】:

          • 我知道这篇文章是 4 年前的,所以这可以解释它。但现在这两个链接都断开了。
          • 将损坏的链接替换为指向其 archive.org 副本的链接
          【解决方案5】:

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

          1) 定义ICommand接口:

          public interface ICommand {
             void Do();
             void Undo();
          }
          

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

          public abstract class WinFormCommand : ICommand {
          
          }
          

          3) 创建命令调用器:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-26
            • 2012-05-12
            • 1970-01-01
            • 1970-01-01
            • 2012-03-27
            • 1970-01-01
            • 1970-01-01
            • 2012-01-08
            相关资源
            最近更新 更多