WPF中的自定义命令

4

我正在开发一个WPF应用程序,其中有一个工具栏/菜单,将使用多个自定义命令。大约15-20个。我已经看到了如何创建自定义命令的文档,但它们都不一定适用于我想做的事情。

我正在使用控制器来处理我的应用程序中的业务逻辑,并且我正在尝试让我的视图完全不做任何逻辑。

我想做的是在项目中创建一个目录,用于保存自定义命令类,以便我可以将它们与控制器和视图解耦,但我仍然希望像普通命令一样从视图中调用它们。

我也看到过DelegateCommand类的使用,但不确定是否要朝这个方向发展。

我希望能够拥有任意自定义命令类,例如以下内容:

public CustomCommand: ICommandd
{
    public bool CanExecute(object parameter)
    {
        //arbitrary logic
    }

    public void Execute(object parameter)
    {

    }
}

我的想法是我会有10-20个这样的命令,我希望将它们与其他内容分开,并在需要时调用它们。

我知道有一种方法可以分离自定义命令,但不太确定。

我是新手,还在努力理解这个概念。

谢谢。

3个回答

4

这个概念是将一个命令绑定到一个按钮上,该命令驱动该按钮的两个属性:"单击"和"启用",从而得到您发布的界面。

你想使用命令的主要原因是能够将按钮点击绑定到视图模型中的操作。

如果你创建一个自定义命令,将一个操作作为构造函数参数,那么你可以直接将视图模型中的方法连接到你的命令上。

public class RelayCommand: ICommandd
{
    Action action;
    Func<bool> canExecute;

    public RelayCommand(Action action) : this(action, () => true) {}
    public RelayCommand(Action action, Func<bool> canExecute) 
    { 
        this.action = action; 
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return canExecute();
    }

    public void Execute(object parameter)
    {
        action();
    }
}

在您的视图模型中使用如下:

public RelayCommand SaveCommand { get; set; }

SaveCommand = new RelayCommand(OnSave);

public void Save()
{
    // save logic...
}

如果您想同时连接CanExecute,您可以使用第二个构造函数并提供一个CanSave方法。

public RelayCommand SaveCommand { get; set; }

SaveCommand = new RelayCommand(OnSave, CanSave);

public void Save()
{
    // save logic...
}

public bool CanSave()
{
    return // ... 
}

你可能已经注意到,在我的实现中,我删除了命令参数。这在大多数情况下是足够的,并且可以节省处理程序方法中的额外参数。对于剩下的10%,我实现了一个RelayCommand<T>,它接受一个Action而不是Action,并更改了Execute方法为:

    public void Execute(object parameter)
    {
        action((T)parameter);
    }

需要一个参数化处理程序。
SaveCommand = new RelayCommand<SomeType>(OnSave);

public void Save(SomeType toSave)
{
    // save logic using parameter
}

这将避免您在使用object变量时遇到的所有类型转换问题,并使您的视图模型保持类型安全。

这确实是一种非常有用的命令执行方式,特别适用于M-V-VM架构,但不幸的是这并不是我正在寻找的,如果你读了上面的内容,我实际上是想将所有逻辑从我的视图中分离出来,我有具体的原因做这个决定,我在这里找到了我要的东西:http://www.codeproject.com/KB/WPF/CentralizingWPFCommands.aspx?display=Print - 不过还是要感谢你提供的很好的例子,谢谢! - TheJediCowboy
即使您想通过静态类提供命令,我也建议使用RelayCommands。这样,您就不需要为xaml文件编写任何后台代码,并且“_DeleteContact = new RoutedUICommand("Delete an existing contact", "DeleteContact", typeof(MyAppCommands));” 包含硬编码字符串,可能会妨碍重构。我对您的用例很感兴趣。为什么要将所有命令放入一个静态类中? - Zebi

1

使用RelayCommand,它不需要您为每个命令创建一个类,您只需将两种方法作为lambda表达式/委托添加到构造函数中即可。

我在我的项目中随处使用它,它真的可以节省时间。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接