因此,在我正在进行的这个特定MVVM实现中,我需要几个命令.我真的厌倦了一个接一个地实现ICommand类,所以我想出了一个解决方案,但我不知道它有多好,所以这里的WPF专家的意见将非常感谢.如果你能提供更好的解决方案,甚至更好.

我所做的是一个ICommand类和两个以对象为参数的委托,一个委托是void(对于OnExecute),另一个是bool(对于OnCanExecute).因此,在我的ICommand的构造函数(由ViewModel类调用)中,我发送两个方法,并在每个ICommand方法上调用委托的方法.

它的效果非常好,但我不确定这是一种不好的方法,还是有更好的方法.以下是完整的代码,任何输入都将不胜感激,即使是否定的,但请具有建设性.

ViewModel:

public class TestViewModel : DependencyObject
{
    public ICommand Command1 { get; set; }
    public ICommand Command2 { get; set; }
    public ICommand Command3 { get; set; }

    public TestViewModel()
    {
        this.Command1 = new TestCommand(ExecuteCommand1, CanExecuteCommand1);
        this.Command2 = new TestCommand(ExecuteCommand2, CanExecuteCommand2);
        this.Command3 = new TestCommand(ExecuteCommand3, CanExecuteCommand3);
    }

    public bool CanExecuteCommand1(object parameter)
    {
        return true;
    }

    public void ExecuteCommand1(object parameter)
    {
        MessageBox.Show("Executing command 1");
    }

    public bool CanExecuteCommand2(object parameter)
    {
        return true;
    }

    public void ExecuteCommand2(object parameter)
    {
        MessageBox.Show("Executing command 2");
    }

    public bool CanExecuteCommand3(object parameter)
    {
        return true;
    }

    public void ExecuteCommand3(object parameter)
    {
        MessageBox.Show("Executing command 3");
    }
}

ICommand:

public class TestCommand : ICommand
{
    public delegate void ICommandOnExecute(object parameter);
    public delegate bool ICommandOnCanExecute(object parameter);

    private ICommandOnExecute _execute;
    private ICommandOnCanExecute _canExecute;

    public TestCommand(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod)
    {
        _execute = onExecuteMethod;
        _canExecute = onCanExecuteMethod;
    }

    #region ICommand Members

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute.Invoke(parameter);
    }

    public void Execute(object parameter)
    {
        _execute.Invoke(parameter);
    }

    #endregion
}

推荐答案

这几乎与Karl Shifflet demonstrateda RelayCommand的情况相同,即Executeemits 预定的Action<T>.一流的解决方案,如果你问我的话.

public class RelayCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public RelayCommand(Predicate<object> canExecute, Action<object> execute)
    {
        _canExecute = canExecute;
        _execute = execute;
    }

    public event EventHandler CanExecuteChanged
    {
        add => CommandManager.RequerySuggested += value;
        remove => CommandManager.RequerySuggested -= value;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

然后这可能会被用作...

public class MyViewModel
{
    private ICommand _doSomething;
    public ICommand DoSomethingCommand
    {
        get
        {
            if (_doSomething == null)
            {
                _doSomething = new RelayCommand(
                    p => this.CanDoSomething,
                    p => this.DoSomeImportantMethod());
            }
            return _doSomething;
        }
    }
}

Read more:
Josh Smith (introducer of RelayCommand): Patterns - WPF Apps With The MVVM Design Pattern

.net相关问答推荐

Docker镜像mcr.microsoft.com/dotnet/aspnet:8.0不能在Windows上构建

为什么Regex.Escape支持数字符号和空格?

如何从 tshark 的 stderr 捕获实时数据包计数?

使用 PEM 文件创建 DSA 签名

防止在 .NET 上构建路径中的反斜杠以进行跨平台部署

为什么这两个比较有不同的结果?

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

.NET 的future 版本会支持 C# 中的元组吗?

设置日志(log)文件名以在 Log4j 中包含当前日期

将客户端证书添加到 .NET Core HttpClient

LINQ:确定两个序列是否包含完全相同的元素

编译错误:显式实现接口时修饰符 'public' 对此项目无效

注册 COM 互操作与使程序集 COM 可见

找不到 Assert.Fail 和 Assert.Pass 或等效项

无法将文件 *.mdf 作为数据库附加

C# 的浮点比较函数

无法使用 Unity 将依赖项注入 ASP.NET Web API 控制器

beforefieldinit 标志有什么作用?

.NET 配置文件 configSource 在应用程序目录文件夹之外

在 .Net 中调用 Web 服务时绕过无效的 SSL 证书错误