我只是在追寻一些关于ICommands的信息,
在我的 WPF 应用程序上,我有添加到 ObservableCollection 的 onClick 事件。所以(ObservableCollection.Add()
但是,我还有 2 个类似的事件要添加到集合中。所以我听说我可以使用 ICommand 接口来"执行"添加/编辑/删除等,所以我不需要这些单独的事件。
有人可以给我一个如何在 MVVM 中执行此操作的示例。(所有添加都在我的观点模型中)
谢谢
您可能想要查看"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);
}
}
在 VM 中,公开如下命令:-
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}
.这是一个节省时间的方法,因为它只是意味着我可以根据需要从单个属性中挂起任意数量的命令,而不是像我之前的示例那样将每个命令公开为单独的属性。