【问题标题】:Should i create a Class for each button in the interface?我应该为界面中的每个按钮创建一个类吗?
【发布时间】:2016-10-11 21:24:08
【问题描述】:

我有一个问题,我看了很多关于 MVVM 的教程,但我仍然感到困惑。 我有一个带有多个按钮的界面,我必须实现 ICommand 界面才能将命令绑定到视图。

我是这样做的:

主要解决方案

Main Solution
    Model
        SomeClass.cs
    ViewModel
        Commands
            SomeCommands.cs
        SomeViewModel.cs

好的,现在在界面中我有多个按钮,每个按钮都做不同的事情,例如,一个用于启动线程,另一个用于取消它,第三个用于另一件事。 我应该为视图上的每个按钮创建一个实现 ICommand 接口的单独类吗?

Main Solution
    Model
        SomeClass.cs
    ViewModel
        Commands
            StartCommands.cs
            CancelCommands.cs
            OtherCommands.cs
        SomeViewModel.cs

我问这个是因为当我实现 ICommand 接口时,我只有一个“Execute”方法和一个“CanExecute”方法。在一个View上通过绑定实现多个按钮的常用方法是什么?

我在网上搜索了一个例子,但没有任何运气......其中很多都很令人困惑,而且肯定不适合像我这样的新手。

另一件事是当我有多个视图和多个视图模型时,我应该创建多个命令文件夹来嵌套它吗?

Main Solution
    Model
        SomeClass.cs
    ViewModel
        FirstCommands
            StartCommands.cs
            CancelCommands.cs
            OtherCommands.cs
        SecondCommands
            StartCommands.cs
            CancelCommands.cs
            OtherCommands.cs
        FirstViewModel.cs
        SecondViewModel.cs

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    恕我直言,在经典的 MVVM 方法中为每个命令设置一个单独的类是一种矫枉过正的做法。使用类似于 MVVMLight 的 RelayCommand(如果你想传递参数,则使用 generic one)。

    然后您可以将您的命令定义为您的 ViewModel 成员,并提供 Execute/CanExecute 实现作为您的 ViewModel 的一部分:

    public RelayCommand MyCommand { get; }
    
    public MyView()
    {
        //[...]
        this.MyCommand = new RelayCommand(this.ExecuteMyCommand, this.CanExecuteMyCommand);
    }
    
    public void ExecuteMyCommand()
    {
       //do work!
    }
    
    public bool CanExecuteMyCommand()
    {
       //optional - control if command can be executed at a given time
    }
    

    您可以在 XAML 中绑定到 MyCommand(假设您的 View 已绑定到您的 ViewModel):

    <Button Content='WORK!' Command='{Binding MyCommand}' />
    

    【讨论】:

    【解决方案2】:

    你想要的是一个DelegateCommand 类。你can use Prism,或者只是在谷歌周围偷一个; here's one on StackOverflow 我没有测试过,但它看起来是合法的。如果您不需要命令的参数,只需忽略 parameter 参数。

    DelegateCommand 实现 ICommand,并调用您传递给其构造函数的 ActionAction&lt;object&gt;,如下所示(来自上面链接的 StackOverflow 答案):

    public DelegateCommand AddFolderCommand { get; protected set; }
    public MyViewModel(ExplorerViewModel explorer)
    {           
        AddFolderCommand = new DelegateCommand(ExecuteAddFolderCommand, (x) => true);
    }
    
    public void ExecuteAddFolderCommand(object param)
    {          
        MessageBox.Show("this will be executed on button click later");
    }
    

    这应该包含在 WPF 中,但由于某种原因没有。

    【讨论】:

    • @exSnake 唯一的区别是名称。番茄,番茄酱。他们做同样的事情。有人称它为一种,有人称它为另一种。有很多实现以任何名称或其他名称执行相同的操作。
    • @exSnake 我个人喜欢 decPL 的强类型泛型参数版本。但请自行选择。
    猜你喜欢
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2016-01-14
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多