寻找 UI 命令模式的示例 [关闭]
-
08-06-2019 - |
题
我正在开发一个 WinForm .Net 应用程序,其基本 UI 包括工具栏按钮、菜单项和击键,所有这些都启动相同的底层代码。现在,每个事件的事件处理程序都调用一个通用方法来执行该功能。
据我所知,这种类型的操作可以由 命令设计模式 具有自动启用/禁用或选中/取消选中 UI 元素的额外好处。
我一直在网上搜索一个好的示例项目,但实际上还没有找到。有人有可以分享的好例子吗?
解决方案
首先让我们确保我们知道命令模式是什么:
命令模式将请求封装为对象,并为其提供已知的公共接口。命令模式确保每个对象都会接收自己的命令,并在发件人和接收方之间提供脱钩。发件人是调用操作的对象,并且接收器是接收请求并在其上行动的对象。
这是给您的一个例子。有很多方法可以做到这一点,但我将采用基于接口的方法来使代码更易于测试。我不确定你喜欢哪种语言,但我是用 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());
}
}
我希望您可以采用这个示例并将其用于您正在开发的应用程序。如果您想获得更多说明,请告诉我。
其他提示
你走在正确的轨道上。基本上您将拥有一个代表文档的模型。您将在 CutCommand 中使用此模型。您将需要更改 CutCommand 的构造函数以接受您想要剪切的信息。然后,每次单击“剪切”按钮时,您都会调用一个新的 CutCommand 并在构造函数中传递参数。然后在调用 Execute 方法时在类中使用这些参数。
尝试开源、.NET 编辑器,例如 夏普开发 或者 记事本++.
(自然)有一些关于命令模式的讨论 http://c2.com/cgi/wiki?CommandPattern 这可能会有所帮助。
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
我无法帮助您提供示例链接,但可以自己提供示例。
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。