我正在开发一个带有基本 UI 的 WinForm .Net 应用程序,其中包括启动相同底层代码的工具栏按钮、菜单项和击键。现在,每个事件处理程序调用一个通用方法来执行该功能。
根据我的阅读,这种类型的操作可以由命令设计模式处理,并具有自动启用/禁用或选中/取消选中 UI 元素的额外好处。
我一直在网上搜索一个好的示例项目,但真的没有找到。有没有人可以分享一个很好的例子?
我正在开发一个带有基本 UI 的 WinForm .Net 应用程序,其中包括启动相同底层代码的工具栏按钮、菜单项和击键。现在,每个事件处理程序调用一个通用方法来执行该功能。
根据我的阅读,这种类型的操作可以由命令设计模式处理,并具有自动启用/禁用或选中/取消选中 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 的构造函数以接受您要剪切的信息。然后,每次单击 Cut 按钮时,您都会调用一个新的 CutCommand 并在构造函数中传递参数。然后在调用 Execute 方法时在类中使用这些参数。
尝试开源的 .NET 编辑器,例如SharpDevelop或Notepad++。
在http://c2.com/cgi/wiki?CommandPattern上(自然)有一些关于命令模式的讨论,这可能会有所帮助。
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
我无法为您提供示例链接,但可以自己提供示例。
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。