Relaycommand和参数的执行方法参数、方法、Relaycommand

2023-09-03 17:46:21 作者:゛╰ゝ萁实ゝ俄們都沒錯ヾ

目前,我正在学习WPF和MVVM,我觉得我得到大部分,它是如何工作的,但我已经遇到一些使用上的RelayCommand(或DelegateCommand),我不明白。我认为这是做的方式代表们的工作。

I'm currently learning WPF and MVVM, I think I get most of it and how it works but I've come across something on using the RelayCommand (or DelegateCommand) that I don't understand. I think it's to do with the way delegates work.

请注意,code以下,而仅仅是在测试解决方案的时刻,所以没有现场code。我也正在考虑这对于不需要参数,如接近和理解,为什么它的工作原理命令。

Please note that the code below is all just in test solutions at the moment, so no live code. Also I am considering this for commands that do not require a parameter such as close and to understand why it works.

所以,如果我采取的约什 - 史密斯创造了RelayCommand( HTTP:/ /msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030 )我可以设置这样的命令:

So if I take the RelayCommand that Josh Smith created( http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030) I can setup a command like this:

RelayCommand updateTextContentCommand;

public ICommand UpdateTextContentCommand
{
    get
    {
        if (updateTextContentCommand == null)
        {
            updateTextContentCommand = new RelayCommand(
                param => this.UpdateTextContentCommand_Execute());
        }
        return updateTextContentCommand;
    }
}

这个execute方法:

with this execute method:

public void UpdateTextContentCommand_Execute()
{
    this.TextContent = DateTime.Now.ToString();
}

我用一个简单的绑定到一个TextBlock看到的结果,并命令绑定到一个按钮。这工作得很好。我不明白的是使用的拉姆达EX pression创建命令。该动作<对象> 需要一个参数,不是吗?那么,为什么这code的工作?

I used a simple binding to a TextBlock to see the result and the command is bound to a button. This works fine. What I don't get is the use of the lambda expression to create the command. The Action<object> expects a parameter doesn't it? so why does this code work?

如果我改变上面的code

If I change the code above to

if (updateTextContentCommand == null)
{
    updateTextContentCommand = new RelayCommand(
        this.UpdateTextContentCommand_Execute());
}

我得到这些错误:

I get these error:

*最好的重载的方法匹配'MVVM.RelayCommandTesting.Framework.RelayCommand.RelayCommand(System.Action)'有一些无效的参数

*The best overloaded method match for 'MVVM.RelayCommandTesting.Framework.RelayCommand.RelayCommand(System.Action)' has some invalid arguments

参数1:无法从空到System.Action转换*

Argument 1: cannot convert from 'void' to 'System.Action'*

和删除()后执行给出了这样的错误:

and removing the () after Execute gives this error:

参数1:无法从方法组'转换为'System.Action的

但是,如果我改变code是这样的:

But if I change the code like this:

if (updateTextContentCommand == null)
{
    updateTextContentCommand = new RelayCommand(
        this.UpdateTextContentCommand_Execute);
}

public void UpdateTextContentCommand_Execute(object param)
{
    this.TextContent = DateTime.Now.ToString();
}

它符合并运行良好。如果我改变了看法使用CommandParameter然后我就可以使用参数使用此方法来设置文本内容,但如果我使用的lambda风格我有一个参数传递给该行因此它这样的参数=> this.UpdateTextContentCommand_Execute(参数)

在我的测试中,我硬编码CommandParameter价值,但我想这很可能会被绑定到视图模型的属性在实际系统中,因此您将能够通过在拉姆达风格的参数数据。

In my test I'm hard coding the CommandParameter value but I guess it would most likely be data bound to a property of the ViewModel in a real system so you would be able to pass the parameter in the lambda style.

任何人都可以解释为什么无参数的版本适用于拉姆达的风格吗?

Can anyone explain why the parameterless version works with the lambda style please?

感谢您抽出宝贵时间来阅读这一点。

Thanks for taking the time to read this.

看来下面的问题中,关于该拉姆达的一些问题,以及,但我不认为它回答我的问题。

It seems the question below had some questions about the lambda as well but I don't see that it answers my question.

Passing使用RelayCommand在视图模型定义(由约什 - 史密斯的例子)参数

推荐答案

构造函数参数是一个委托具有以下签名:

The constructor parameter is a delegate that has the following signature:

void MethodName(T parameter)

其中,参数的类型是 T (在RelayCommand这将是类型的情况下 System.Object的

where parameter is of type T (in the case of the RelayCommand this will be of type system.Object.

这code:

param => this.UpdateTextContentCommand_Execute()

是一个拉姆达 EX pression,基本上扩展到这样的:

is a lambda expression that essentially expands to this:

void AnonymousMethod(object param)
{
    this.UpdateTextContentCommand_Execute();
}

因此​​,在这种情况下,您是传递一个参数(参数)你只是不使用它。 如果你明白这一点,那么你现在应该知道为什么你的其他例子的行为,他们做的方式。

So in this case you are passing in a parameter (param) you are just not using it. If you understand this then you should now realise why your other examples behave the way they do.

示例1

if (updateTextContentCommand == null)
{
    updateTextContentCommand = new RelayCommand(
        this.UpdateTextContentCommand_Execute());
}

在这里,你是要求的返回无效的方法。构造函数期待的东西相匹配的动作&LT; T&GT; 委托因此误差

Here you are calling the method which returns void. The constructor is expecting something that matches the Action<T> delegate hence the error.

例2

如果你再取出支架是这样的:

If you then remove the brackets like this:

if (updateTextContentCommand == null)
{
    updateTextContentCommand = new RelayCommand(
        this.UpdateTextContentCommand_Execute);
}

把这看作是类似订阅的事件了一下:

Think of this as being a bit like subscribing to an event:

myObject.myevent += new Action<object>(this.UpdateTextContentCommand_Execute);

其可以简化为:

which can be shortened to:

myObject.myevent += this.UpdateTextContentCommand_Execute;

所以,构造函数接受具有签名匹配行动 - 的任何方法; T&GT; 代表签字即

void UpdateTextContentCommand_Execute(object parameter)

您的方法有以下签名:

void UpdateTextContentCommand_Execute()

正如你所看到的签名不匹配,因此编译器抱怨。

As you can see the signatures don't match so the compiler complains.

当你更新你的 UpdateTextContentCommand_Execute 方法接受一个对象参数中的签名一致,现在这就是为什么它现在的作品。

When you update your UpdateTextContentCommand_Execute method to accept an object parameter it's signature now matches which is why it now works.