.net RelayCommand不启动CAN执行

.net RelayCommand不启动CAN执行,.net,silverlight,windows-phone-7,mvvm,mvvm-light,.net,Silverlight,Windows Phone 7,Mvvm,Mvvm Light,我正在尝试创建一个绑定到按钮的命令,该命令依赖于viewmodels的层次结构来表示wp7应用程序中的透视和透视项。它是这样的(我将尽可能省略样板代码): 父视图模型: public RelayCommand刷新命令 { 得到 { 返回刷新命令; } 设置 { 如果(_refreshCommand==值) { 返回; } var oldValue=\u刷新命令; _刷新命令=值; //更新绑定,无广播 RaisePropertyChanged(RefreshCommandPropertyName

我正在尝试创建一个绑定到按钮的命令,该命令依赖于viewmodels的层次结构来表示wp7应用程序中的透视和透视项。它是这样的(我将尽可能省略样板代码):

父视图模型:

public RelayCommand刷新命令
{
得到
{
返回刷新命令;
}
设置
{
如果(_refreshCommand==值)
{
返回;
}
var oldValue=\u刷新命令;
_刷新命令=值;
//更新绑定,无广播
RaisePropertyChanged(RefreshCommandPropertyName);
}
}
公共RelayCommand loaded命令
{
得到
{
操作getCurrentViewmodel=(参数)=>
{
CurrentViewModel=SearchByLocationViewModel;//也许有更好的。。。
RefreshCommand=CurrentViewModel.RefreshResultsCommand;
RefreshCommand.RaiseCanExecuteChanged();
};
返回新的RelayCommand(getCurrentViewmodel);
}
}
公共中继命令数据透视项更改命令
{
得到
{
操作数据透视更改=(参数)=>
{
如果(args!=null)
{
//更新当前视图模型
CurrentViewModel=((Microsoft.Phone.Controls.PivotItem)args.AddedItems[0])。DataContext作为ISearchViewModelBase;
RefreshCommand=CurrentViewModel.RefreshResultsCommand;
}
};
返回新的RelayCommand(数据透视已更改);
}
}
因此,每次加载时,我都将父视图模型的RefreshCommand属性设置为子命令,当选定的数据透视项更改时,我也会这样做

Xaml


子视图模型

public Func可以刷新
{
获取{return()=>!IsLoading;}
}
私人中继命令刷新结果命令;
公共关系命令刷新结果命令
{
得到
{
动作doRefresh=()=>
{
SearchResults.Clear();
这是._pageNumber=0;
AddItems();
};
返回RefreshResultCommand=RefreshResultCommand??新的RelayCommand(doRefresh,CanRefresh);
}
}
发生的情况是,永远不会调用CanRefresh。这些命令工作正常,这取决于它调用一个附加项(这是一个在每个子viewmodel中以不同方式实现的虚拟方法)或另一个附加项的数据透视项,但就像CanExecute从未被引发一样。我正在使用MVVM Light工具包。
谢谢

每次调用
LoadedCommand
PivotChangedCommand
属性时,您都在创建一个新的中继命令。由于SL/WPF非常频繁地调用这些属性,因此您必须确保不在每次调用该属性时都创建命令。实际上,您的
RefreshResultCommand
实现了正确的模式

确保正确实现属性/命令的最佳方法是使用。将它们下载到您的代码段目录,然后直接使用它们。除了总是生成相同的样板代码,从而提高质量之外,它们还大大加快了速度


您也可以安装代码段。

我怀疑从未调用
CanExecute
方法,因为
RelayCommand
CanExecuteChanged
事件从未在视图层当前绑定到的视图模型对象上触发。由于要在大多数属性访问上创建命令,因此有很多关于的命令,并且很可能是在视图层尚未绑定到的命令或不再绑定到的命令上触发事件


我从未见过有人在每次调用属性getter时都创建新命令。您是否可以尝试在构造函数中创建一次命令,而不是在每个属性访问中创建一次命令,看看这是否解决了问题?

当您说“永远不会调用CanRefresh”时,您是指
CanRefresh
属性还是其中的lambda?你怎么知道它从未被调用过?@DanielPerez:你确实在调用
RaiseCanceTechChanged
方法,很抱歉没有注意到它。不过,它隐藏得很好。我已经更新了我的答案。
<Button Command="{Binding RefreshCommand}" />