C# 不使用命令调用ViewModel中的方法
我有以下情况:C# 不使用命令调用ViewModel中的方法,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我有以下情况: public class MyCommand : ICommand { MyViewModel _viewModel; public MyCommand(MyViewModel viewModel) { _viewModel = viewModel; } public bool CanExecute(object parameter) { return true; } publi
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属性中调用的方法名称
我希望其他人能为这个问题提供一个优雅的解决方案。您可以使用MVVMLight中的RelayCommand或PRISM中的DelegateCommand。它们都将给出一种实现命令的通用方法。 甚至可以创建自己的公共命令类并使用它。参考下面的示例
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);
}
}
公共类视图模型:INotifyPropertyChanged
{
public BaseCommand GetDataCommand{get;set;}
公共视图模型()
{
GetDataCommand=新的BaseCommand(GetData);
}
私有void GetData(对象参数)
{
}
}
公共类BaseCommand:ICommand
{
私有谓词_canExecute;
私人行动法;
公共事件事件处理程序CanExecuteChanged
{
添加
{
CommandManager.RequerySuggested+=值;
}
去除
{
CommandManager.RequerySuggested-=值;
}
}
public BaseCommand(操作方法,谓词canExecute=null)
{
_方法=方法;
_canExecute=canExecute;
}
公共布尔CanExecute(对象参数)
{
如果(_canExecute==null)
{
返回true;
}
返回_canExecute(参数);
}
public void Execute(对象参数)
{
_方法调用(参数);
}
}
您可以使用MVVMLight中的RelayCommand或PRISM中的DelegateCommand。它们都将给出一种实现命令的通用方法。
甚至可以创建自己的公共命令类并使用它。参考下面的示例
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);
}
}
公共类视图模型:INotifyPropertyChanged
{
public BaseCommand GetDataCommand{get;set;}
公共视图模型()
{
GetDataCommand=新的BaseCommand(GetData);
}
私有void GetData(对象参数)
{
}
}
公共类BaseCommand:ICommand
{
私有谓词_canExecute;
私人行动法;
公共事件事件处理程序CanExecuteChanged
{
添加
{
CommandManager.RequerySuggested+=值;
}
去除
{
CommandManager.RequerySuggested-=值;
}
}
public BaseCommand(操作方法,谓词canExecute=null)
{
_方法=方法;
_canExecute=canExecute;
}
公共布尔CanExecute(对象参数)
{
如果(_canExecute==null)
{
返回true;
}
返回_canExecute(参数);
}
public void Execute(对象参数)
{
_方法调用(参数);
}
}
您可以使用中的“”操作从视图中调用视图模型上的方法。它看起来像这样:
<Button ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="MyMethod" TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
但是,使用命令仍然被认为是最佳实践。正如Ayyappan提到的,您可以使用这样的库,这样就不必编写自己的ICommand实现
PS:另请参见您可以使用“”操作从视图中调用视图模型上的方法。它看起来像这样:
<Button ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="MyMethod" TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
但是,使用命令仍然被认为是最佳实践。正如Ayyappan提到的,您可以使用这样的库,这样就不必编写自己的ICommand实现
PS:另请参见1)这并不是最好的方法2)您可以直接调用该方法,但您必须跳过UI中的白痴环才能执行此操作,这比使用ICommand模式更昂贵。您还将逻辑分为两部分,即
视图
和视图模型
,如果有人来维护此代码,他们必须查看两个位置,而不是一个位置,即ViewModel
。1)这不是最好的方法2)您可以直接调用此方法,但是,您必须跳过UI中的白痴圈来完成比使用ICommand模式更昂贵的操作。您还将逻辑拆分为两部分,即View
和ViewModel
,如果有人愿意来维护此代码,则他们必须在2个位置而不是一个位置查看,即ViewModel
。