带参数的ICommand

时间:2015-03-23 23:04:38

标签: c# wpf mvvm

我发现了这个:Close Window from ViewModel让我开始修改我的DelegateCommand类来处理参数。但是我无法解决语法问题。

这是我的DelegateCommand类,以及我试图创建的DelegateCommand类,但收效甚微:

    public class DelegateCommand : ICommand
    {
        private readonly Action _action;

        public DelegateCommand(Action action)
        {
            _action = action;
        }

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

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

#pragma warning disable 67
        public event EventHandler CanExecuteChanged { add { } remove { } }
#pragma warning restore 67
    }

    public class DelegateCommand<T> : ICommand
    {
        private readonly Action _action;

        public DelegateCommand(Action action)
        {
            _action = action;
        }

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

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

#pragma warning disable 67
        public event EventHandler CanExecuteChanged { add { } remove { } }
#pragma warning restore 67
    }

以下是我在viewmodel中所做的事情:

public ICommand RowEditEndingAction
{
    get { return new DelegateCommand(RowEditEnding); }
}

public ICommand UpdateDatabaseClick
{
    get { return new DelegateCommand<object>(UpdateDatabase); } //THIS LINE HAS THE ERROR
}

将被调用的实际方法:

public void UpdateDatabase(object parameter)
{
    Window w = (Window)parameter;
    // A bunch of stuff that works is removed for brevity
    w.Close();
}

编译器不喜欢我的UpdateDatabaseClick,特别是说DelegateCommand的参数有问题,但我不知道我做错了什么(虽然我认为它是语法......)。我需要改变什么?在将参数添加到UpdateDatabase之前,这一切都有效,并且只有DelegateCommand(没有模板类)。但在那种情况下,我无法关闭窗户。

2 个答案:

答案 0 :(得分:3)

这是您正在呼叫的DelegateCommand<T>班级的构造函数:

public DelegateCommand(Action action)

以下是您的称呼方式:

new DelegateCommand<object>(UpdateDatabase)

在那里,UpdateDatabase声明如下:

public void UpdateDatabase(object parameter)

现在,您正在调用的构造函数需要Action。这是一个没有返回值的无参数方法。

但是,您传递的方法带有一个参数。这就是编译器所抱怨的。

您实际可能想要做的是接受任何方法一个参数 - 为此,您可以使用类型Action<T>。由于您的参数应该具有与作为DelegateCommand<T>类的类型参数传递的相同类型,因此您可以像这样声明构造函数:

public DelegateCommand(Action<T> action)

现在,您还需要更新存储操作的支持字段的类型:

private readonly Action<T> _action;

最后,由于_action现在需要一个参数,因此在_action中调用DelegateCommand<T>.Execute时需要传递该参数。通常,您希望将作为参数接收的parameter对象移交给Execute方法。但是,该值始终键入object,而您希望在方法中使用类型为T的强类型值。因此,您还必须添加额外的强制转换:

public void Execute(object parameter)
{
    _action((T)parameter);
}

答案 1 :(得分:0)

我建议你试试Prism框架。它具有使用MVVM模型的WPF应用程序所需的所有组件,工具。