【问题标题】:ICommand help to replace button eventsICommand 帮助替换按钮事件
【发布时间】:2014-04-07 15:07:00
【问题描述】:

我只是在了解有关 ICommands 的一些信息,

在我的 WPF 应用程序中,我有添加到 ObservableCollection 的 onClick 事件。所以 (ObservableCollection.Add()

但是,我也有 2 个类似的事件要添加到集合中。所以我听说我可以使用 ICommand 接口来“执行”添加/编辑/删除等,所以我不需要这些单独的事件。

谁能提供我如何在 MVVM 中执行此操作的示例。 (所有添加都在我的 ViewModel 中)

谢谢

【问题讨论】:

  • 谢谢,看起来不错。但是,如果我想使用命令添加,我是否使用
  • 除非我遗漏了什么,否则它应该像将 MV 命令绑定到按钮的 Command 属性一样简单。

标签: wpf mvvm observablecollection icommand


【解决方案1】:

您可能想查看“RelayCommand”——它是 ICommand 的常见实现,可以简化您的视图模型代码,允许您为 ICommand 的“Execute”和“CanExecute”方法指定委托。你会在网上找到很多实现,但这是我使用的:

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        this._execute = execute;
        this._canExecute = canExecute;
    }

    public virtual bool CanExecute(object parameter)
    {
        return this._canExecute == null || this._canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public virtual void Execute(object parameter)
    {
        this._execute(parameter);
    }
}

在您的虚拟机中,公开如下命令:-

public ICommand FooCommand
{
    get
    {
        if (_fooCommand == null)
        {
            _fooCommand = new RelayCommand(ExecuteFooCommand, CanDoFooCommand);
        }
        return _fooCommand;
    }
}

private void ExecuteFooCommand(object commandParameter)
{
    // Code to execute the command.
}

private bool CanDoFooCommand()
{
    // Code that indicates whether the command can be executed.
    // This will manifest itself in the view by enabling/disabling the button.
}

由于 RelayCommand ctr 参数是委托,你当然可以这样做:-

new RelayCommand(o => { // do something }, o => true);

最后,将你的命令绑定到你的视图按钮:-

<Button Content="Click me" Command="{Binding FooCommand}" ... />

您也可以将参数传递给命令委托:-

<Button Content="Click me" Command="{Binding FooCommand}" CommandParamter="123" />

(凭记忆写出,因此在语法上可能不是 100% 正确!)

更进一步……

为了进一步简化事情,我使用动态属性将 VM 命令公开给视图。在我的 VM 基类中,我具有以下属性:-

    public dynamic Commands
    {
        get
        {
            return _commands;
        }
    }

然后在 VM 的构造函数中,我可以像这样创建它的所有命令:-

Commands.FooCommand = new RelayCommand(.....
Commands.BarCommand = ..etc..

在我的 XAML 中,我绑定如下命令:- Command={Binding Commands.FooCommand}。 这是一个节省时间的方法,因为它只是意味着我可以根据需要从单个属性中挂起任意数量的命令,而不是像我之前的示例中那样将每个命令公开为单独的属性。

【讨论】:

  • 谢谢安德鲁,非常有用。我是否在 VM 中声明了 ICommand 的一个属性?并使用 CommandParameter 执行我在 VM 中的事件?谢谢
  • 通常,您将为视图中的每个按钮公开一个单独的 ICommand 属性,但“这取决于”您的按钮在做什么。例如,您可能有一系列用于播放不同声音的按钮 - 在这里您可以在 VM 中公开一个“PlaySound”ICommand,并使用每个按钮上的 CommandParameter 来指定要播放的 wav 文件的名称。跨度>
  • @user3428422 如果您在 XAML 中提供 CommandParameter,则在执行命令时(通过单击按钮),参数值将传递给 RelayCommand 的执行委托(上面的“ExecuteFooCommand”方法示例)。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
相关资源
最近更新 更多