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应该有一个参数才能工作。但出于某种原因,即使没有参数,它也能工作。我遗漏了什么吗?