【问题标题】:Call a method in the ViewModel without a command无需命令即可调用 ViewModel 中的方法
【发布时间】:2015-03-12 18:59:29
【问题描述】:

我有以下场景:

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中调用的方法名称> 我的按钮上的属性。

我希望其他人可以为这个问题提供一个优雅的解决方案。

【问题讨论】:

  • 1) 这不是最好的处理方式 2) 您可以直接调用该方法,但您必须跳过 UI 中的白痴圈才能做到这一点,这比使用更昂贵ICommand 模式。
  • 您还将逻辑拆分为两部分,即ViewViewModel,如果有人愿意来维护此代码,他们将不得不在两个地方而不是一个地方查看,即ViewModel.

标签: c# wpf xaml mvvm


【解决方案1】:

您可以使用Blend SDK 中的“CallMethodAction”操作从您的视图中调用视图模型上的方法。它看起来像这样:

<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 实现。

PS:另见WPF: MVVM: Command vs CallMethodAction?

【讨论】:

    【解决方案2】:

    您可以使用来自 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);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 2015-06-28
      • 2018-03-01
      • 2019-06-02
      • 2015-03-15
      • 1970-01-01
      相关资源
      最近更新 更多