Wpf 需要了解MVVM教程、RelayCommand的帮助吗

Wpf 需要了解MVVM教程、RelayCommand的帮助吗,wpf,Wpf,我在读教程 我不明白下面的代码试图做什么 _saveCommand = new RelayCommand(param => this.Save(), param => this.CanSave ); 正如realy命令类中定义的那样,CanSave应该是一个带有参数的方法,因为它映射到谓词,因此它对应的编码方法应该有一个参数,对于action对象也是如此。请帮助理解。RelayCommand更精确地使用函数,将委托传递到其构造函数以实现CanExecute和Execute方法 在

我在读教程

我不明白下面的代码试图做什么

_saveCommand = new RelayCommand(param => this.Save(), param => this.CanSave ); 
正如realy命令类中定义的那样,CanSave应该是一个带有参数的方法,因为它映射到谓词,因此它对应的编码方法应该有一个参数,对于action对象也是如此。请帮助理解。

RelayCommand更精确地使用函数,将委托传递到其构造函数以实现CanExecute和Execute方法

在此示例中,传递了两个函数。首先描述如何保存-仅调用RelayCommand所有者上的save方法。另一个描述了如何检查是否可以保存—只需检查所有者CanSave属性的当前状态

这样,您就不必显式地创建自己的命令类

UPD:


谢谢,但我的问题是Save属于Action类型,定义为Action,根据我的理解,Save应该有一个参数才能工作。但出于某种原因,即使没有参数,它也能工作

好的,让我们仔细看看

 _saveCommand = new RelayCommand(param => this.Save(), param => this.CanSave ); 
在C v2.0的语法中相当于

 _saveCommand = new RelayCommand(
     new Action<object>(delegate(object param){ this.Save(); }), 
     new Func<object,bool>(delegate(object param){ return this.CanSave; })); 
因此,创建匿名函数包装实际方法,让您有权使用或不使用它们自己的参数

如果您想更深入,上面的代码会被编译成如下内容:

 // it is OK to ignore methods arguments. 
 // So, it's also OK to ignore them in anonymous methods as well
 private void Save_Anonymous(object parameter){
     this.Save();
 }
 private bool CanSave_Anonymous(object parameter){
     return this.CanSave;
 }

 ....

 _saveCommand = new RelayCommand(new Action<object>(this.Save_Anonymous), 
        new Func<object, bool>(this.CanSave_Anonymous));
请注意,编译器可以选择其他实现委托的策略,这取决于委托从周围上下文中包含的值。例如,如果您的匿名函数引用了某些局部变量,编译器将生成包含这些变量的匿名类,并将方法放入此类中。

让我们简化它 首先,RelayCommand不是WPF的一部分。它是WPFlight工具包中的一个类,我们可以自由编写自己的实现。 它充当WPF ICommand顶部的包装器,并提供两个方面:操作和谓词。例如,谓词部分可用于根据某些条件启用或禁用按钮。动作部分应包含执行命令时应运行的逻辑

与大多数概念一样,这也有许多可能的方法

方法1

为动作和谓词编写显式命名方法。下面是示例代码

class demoViewModel
{
    string filename = "";
    private ICommand _saveCommand;
    public ICommand SaveCommand
    {
        get
        {
            if (_saveCommand== null)
            {
                _saveCommand = new RelayCommand<object>(
                     action => Save(filename),
                     predicate => CanSave(filename));

            }
            return _saveCommand;
        }
    }

    private bool CanSave(string fname)
    {
        return (!string.IsNullOrEmpty(fname));
    }

    private void Save(string fname)
    {
        SaveHelper(fname);//some logic goes inside SaveHelper
    }        
}
方法2

这里我们将使用匿名方法。这减少了许多代码行,使整个代码更具可读性

class demoViewModel1
{
    string filename = "";
    private ICommand _saveCommand;
    public ICommand SaveCommand
    {
        get
        {
            if (_saveCommand== null)
            {
                _saveCommand = new RelayCommand<object>(
                     action => { SaveHelper(filename); },
                     predicate => { return (!string.IsNullOrEmpty(filename)); }
                     );

            }
            return _saveCommand;
        }
    }
}
方法3

充分利用lambda表达式

class demoViewModel2
{
    string filename = "";
    private ICommand _saveCommand;
    public ICommand SaveCommand
    {
        get
        {
            if (_saveCommand== null)
            {
                _saveCommand = new RelayCommand<object>(
                     (objParamForAction) => { SaveHelper(filename); },
                     () => { return (!string.IsNullOrEmpty(filename)); }
                     );

            }
            return _saveCommand;
        }
    }
}

谢谢,但我的问题是Save属于Action类型,定义为Action,根据我的理解,Save应该有一个参数才能工作。但出于某种原因,即使没有参数,它也能工作。我遗漏了什么吗?