我正在尝试创建一个绑定到按钮的命令,该命令依赖于视图模型的层次结构来表示wp7应用程序中的枢轴和枢轴标题。它是这样的(我将尽可能省略更多的样板代码):
public RelayCommand RefreshCommand
{
get
{
return _refreshCommand;
}
set
{
if (_refreshCommand == value)
{
return;
}
var oldValue = _refreshCommand;
_refreshCommand = value;
// Update bindings, no broadcast
RaisePropertyChanged(RefreshCommandPropertyName);
}
}
public RelayCommand<RoutedEventArgs> LoadedCommand
{
get
{
Action<RoutedEventArgs> getCurrentViewmodel = (args) =>
{
CurrentViewModel = SearchByLocationViewModel; // maybe something better...
RefreshCommand = CurrentViewModel.RefreshResultsCommand;
RefreshCommand.RaiseCanExecuteChanged();
};
return new RelayCommand<RoutedEventArgs>(getCurrentViewmodel);
}
}
public RelayCommand<SelectionChangedEventArgs> PivotItemChangedCommand
{
get
{
Action<SelectionChangedEventArgs> pivotChanged = (args) =>
{
if (args != null)
{
// update current viewmodel
CurrentViewModel = ((Microsoft.Phone.Controls.PivotItem) args.AddedItems[0]).DataContext as ISearchViewModelBase;
RefreshCommand = CurrentViewModel.RefreshResultsCommand;
}
};
return new RelayCommand<SelectionChangedEventArgs>(pivotChanged);
}
}因此,每次加载父视图模型时,我都会将父视图模型的RefreshCommand属性设置为子命令,当选定的透视项发生更改时,我也会这样做。
Xaml
<Button Command="{Binding RefreshCommand}" />子视图模型
public Func<bool> CanRefresh
{
get { return () => !IsLoading; }
}
private RelayCommand refreshResultsCommand;
public RelayCommand RefreshResultsCommand
{
get
{
Action doRefresh = () =>
{
SearchResults.Clear();
this._pageNumber = 0;
AddItems();
};
return refreshResultsCommand = refreshResultsCommand ?? new RelayCommand(doRefresh, CanRefresh);
}
}实际情况是,CanRefresh永远不会被调用。这些命令可以很好地工作,这取决于它调用的pivotitem是一个AddItems (这是一个在每个子视图模型中以不同方式实现的虚拟方法)还是另一个,但它就像CanExecute从未被引发过一样。谢谢!
发布于 2012-02-19 01:41:44
我怀疑CanExecute方法永远不会被调用,因为RelayCommand的CanExecuteChanged事件永远不会在视图层当前绑定到的视图模型对象上触发。由于您是在大多数属性访问上创建命令,因此有很多命令,很可能是在尚未绑定到视图层的命令上或在不再绑定到的命令上触发事件。
我从未见过任何人在每次调用属性getter时创建新命令。您是否可以尝试在构造函数中创建一次命令,而不是在每次访问属性时创建命令,并查看是否可以修复问题?
发布于 2012-02-19 01:15:49
那么,每次调用LoadedCommand和PivotChangedComman属性时,您都会创建一个新的中继命令。由于SL/WPF非常频繁地调用这些属性,因此您必须确保不会在每次调用属性时都创建命令。实际上,您的RefreshResultsCommand实现了正确的模式。
确保正确实现属性/命令的最好方法是使用Laurent's MVVM snippets。将它们下载到您的snippet目录并使用它们。除了总是产生相同的样板代码,从而提高质量,他们也加速了相当多!
您也可以使用use the installer来安装这些代码片段。
https://stackoverflow.com/questions/9340591
复制相似问题