我有以下情况:
public class MyCommand : ICommand
{
MyViewModel _viewModel;
public MyCommand(MyViewModel viewModel)
{
_viewModel = viewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_viewModel.SomeMethod();
}
}
基本上,当单击一个按钮时,此命令将简单地调用ViewModel中的方法。 CanExecute 始终返回true。
问题在于,即使这通常被认为是最好的做事方式,但它并不优雅。它引出了为什么我需要一个命令来完成这个非常简单的过程的问题。
为什么我不能跳过命令,直接调用该方法?
我已经考虑过这一点,我能看到实现这一目标的唯一方法是创建一个命令,我可以在 CommandParameter <中指定我想要调用的方法名称/ strong>我按钮上的属性。
我希望其他人可以为这个问题提供一个优雅的解决方案。
答案 0 :(得分:4)
您可以使用CallMethodAction中的“Blend SDK”操作从视图中调用视图模型上的方法。它看起来像这样:
<Button ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="MyMethod" TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
然而,仍然认为使用命令的最佳做法。正如Ayyappan所提到的,您可以使用像MVVM Light Toolkit这样的库,这样您就不必编写自己的ICommand实现了。
答案 1 :(得分:2)
您可以使用来自MVVMLight的RelayCommand或来自PRISM的DelegateCommand。它们都将提供一种实现命令的通用方法。 甚至你可以创建自己的Common命令类并使用它。请参阅下面的示例。
public class ViewModel : INotifyPropertyChanged
{
public BaseCommand GetDataCommand { get; set; }
public ViewModel()
{
GetDataCommand = new BaseCommand(GetData);
}
private void GetData(object param)
{
}
}
public class BaseCommand : ICommand
{
private Predicate<object> _canExecute;
private Action<object> _method;
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public BaseCommand(Action<object> method, Predicate<object> canExecute=null)
{
_method = method;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_method.Invoke(parameter);
}
}