如何在ViewModel中为WPF / MVVM简化命令的实现?

时间:2013-01-30 22:36:58

标签: wpf mvvm delegatecommand

我注意到我在ViewModel上为MVVM-WPF场景实现命令时重复了很多代码。如下所示,标准实现由类型为ICommand的公共只读字段,私有DelegateCommand字段和执行逻辑的方法组成。 DelegateCommandICommand的get-accessor中初始化。

考虑到每个命令的重复,如何压缩这种方法?

private DelegateCommand saveCommand;
private DelegateCommand commandClearInputFileList;
private DelegateCommand commandInputFilesDeleteSelected;

public ICommand SaveCommand {
    get {
        if (saveCommand == null) {
            saveCommand = new DelegateCommand(CommitDataBasePush);
        }
        return saveCommand;
    }
}

public ICommand CommandClearInputFileList {
    get {
        if (commandClearInputFileList == null) {
            commandClearInputFileList = new DelegateCommand(InputFilesClear);
        }
        return commandClearInputFileList;
    }
}

public ICommand CommandInputFilesDeleteSelected {
    get {
        if (commandInputFilesDeleteSelected == null) {
            commandInputFilesDeleteSelected = new DelegateCommand(InputFilesDeleteSelected);
        }
        return commandInputFilesDeleteSelected;
    }
}

3 个答案:

答案 0 :(得分:4)

除了空合并运算符之外,您还可以使用Lazy Loading

private Lazy<DelegateCommand> _cmd = new Lazy<DelegateCommand>(() => new DelegateCommand(InputFilesClear) );

public ICommand CommandClearInputFileList { get { return _cmd.Value; } }

就个人而言,我已经放弃了支持Caliburn.Micro框架提供的约定的命令。上面的命令将简单地用公共方法替换。

答案 1 :(得分:3)

就个人而言,我越来越喜欢这种风格了:

    private DelegateCommand saveCommand;
    public ICommand SaveCommand 
    {
        get 
        {
            return saveCommand ?? 
                (saveCommand = new DelegateCommand(CommitDataBasePush));
        }
    }

答案 2 :(得分:1)

您可以将DelegateCommand及其延迟初始化包装到一个简单的自定义命令类中,该类实现ICommand。我将其称为LazyCommand,其用法就像这样简单:

// Declaration
public ICommand SomeCommand { get; private set; }

// Definition
SomeCommand = new LazyCommand(ExecuteSomeCommandMethod);

班级LazyCommand如下所示:

public class LazyCommand : ICommand
{
    private readonly Lazy<DelegateCommand> _innerCommand;

    public LazyCommand(Action executeAction, Func<bool> canExecuteAction = null)
    {
        _innerCommand = canExecuteAction == null ? 
            new Lazy<DelegateCommand>(() => new DelegateCommand(executeAction)): 
            new Lazy<DelegateCommand>(() => new DelegateCommand(executeAction, canExecuteAction));
    }

    public bool CanExecute(object parameter)
    {
        return _innerCommand.Value.CanExecute();
    }

    public void Execute(object parameter)
    {
        _innerCommand.Value.Execute();
    }

    public event EventHandler CanExecuteChanged
    {
        add { _innerCommand.Value.CanExecuteChanged += value; }
        remove { _innerCommand.Value.CanExecuteChanged -= value; }
    }

    public void RaiseCanExecuteChanged()
    {
        _innerCommand.Value.RaiseCanExecuteChanged();
    }
}

让我知道它是否适合您。干杯...