wpf 带参数的 ICommand

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29222069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:01:40  来源:igfitidea点击:

ICommand with Parameter

c#wpfmvvm

提问by Paul Gibson

I found this: Close Window from ViewModelwhich gets me started down the path of modifying my DelegateCommand class to handle parameters. But I am not able to get the syntax worked out.

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

Here is my DelegateCommand class, and the DelegateCommand class that I'm trying to create with little success:

这是我的 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
    }

And here is what I do in the viewmodel:

这是我在视图模型中所做的:

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

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

And the actual method that will get called:

以及将被调用的实际方法:

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

The compiler does not like my UpdateDatabaseClick, specifically saying there is something wrong with the arguments to DelegateCommand, but I am at a loss as to what I am doing wrong (though I am thinking it is syntax . . . ). What do I need to change? This all worked before I added the parameter to UpdateDatabase, and just had the DelegateCommand (no template class). But in that case I could not close the window.

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

回答by O. R. Mapper

Here's the constructor of your DelegateCommand<T>class that you are calling:

DelegateCommand<T>是您正在调用的类的构造函数:

public DelegateCommand(Action action)

And here is how you call it:

这是你如何称呼它的:

new DelegateCommand<object>(UpdateDatabase)

In there, UpdateDatabaseis declared as follows:

在那里,UpdateDatabase声明如下:

public void UpdateDatabase(object parameter)

Now, the constructor you are invoking expects an Action. That is a parameterlessmethod without a return value.

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

However, you are passing in a method with one parameter. That is what the compiler complains about.

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

What you actually probably want to do is to accept any method with one parameter- for that, you can use the type Action<T>. As your parameter should presumeably have the same type that is passed as a type argument to your DelegateCommand<T>class, you can declare your constructor like this:

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

public DelegateCommand(Action<T> action)

Now, you also need to update the type of your backing field where you store the action:

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

private readonly Action<T> _action;

Lastly, as _actionnow expects an argument, you need to pass that argument when invoking _actionin DelegateCommand<T>.Execute. Normally, you want to hand over the parameterobject you receive as an argument to the Executemethod. However, that value is always typed to object, whereas you want to work with a strongly-typed value of type Tin your method. Therefore, you will also have to add an additional cast:

最后,正如_action现在期望的参数一样,您需要在调用_actionin时传递该参数DelegateCommand<T>.Execute。通常,您希望将parameter收到的对象作为Execute方法的参数传递。但是,该值始终键入为object,而您希望T在方法中使用类型为强类型的值。因此,您还必须添加额外的演员表:

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

回答by Thai Anh Duc

I suggest you try Prism framework. It has all the component, tools, you need to work with WPF application with MVVM model.

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