WPF按钮命令,为什么在ViewModel中使用逻辑代码?

时间:2019-01-03 07:02:24

标签: wpf

我已经阅读了一些有关如何使用WPF ListView命令绑定的主题。

Passing a parameter using RelayCommand defined in the ViewModel Binding Button click to a method Button Command in WPF MVVM Model How to bind buttons in ListView DataTemplate to Commands in ViewModel?

所有建议在ViewModel类中编写逻辑代码,例如:

  public RelayCommand ACommandWithAParameter
  {
     get
     {
        if (_aCommandWithAParameter == null)
        {
           _aCommandWithAParameter = new RelayCommand(
               param => this.CommandWithAParameter("Apple")
               );
        }

        return _aCommandWithAParameter;
     }
  }

  public void CommandWithAParameter(String aParameter)
  {
     String theParameter = aParameter;
  }

这是一个好习惯,还是我可以将CommandWithAParameter()移出ViewModel吗?

1 个答案:

答案 0 :(得分:1)

原则上,MVVM应用程序应该能够充分发挥其潜力,而无需创建视图。如果逻辑的某些部分在View类中,那是不可能的。

最重要的是,ICommand具有CanExecute,如果不应运行该命令,它将自动禁用按钮,菜单项等。

我了解为什么通过基本的RelayCommand实现很难看到其好处,但请看一下ReactiveCommand samples

ReactiveCommand可以很好地处理异步工作,甚至在工作完成时禁用按钮,然后再启用它。

简短示例:您有一个登录表单。如果用户名和密码为空,则要禁用登录按钮。

使用命令,您只需将CanExecute设置为false即可。

使用事件时,您已经手动禁用/启用了按钮,请记住,它必须在Dispatcher线程中完成,依此类推-如果您有5个按钮(取决于不同的属性),它将变得非常混乱。

对于ListView,命令也很有用-您可以将当前项绑定为命令参数:

<ListView ItemsSource="{Binding MyObjects}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                      <!-- change the context to parent ViewModel and pass current element to the command -->
                <Button DockPanel.Dock="Right" Command="{Binding ElementName=Root, Path=ViewModel.Delete}" CommandParameter="{Binding}">Delete</Button>

                <TextBlock Text="{Binding Name}"/>
            </DockPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>