我正在尝试通过以下方法创建MVVM Light RelayCommand
:
protected RelayCommand NavigateToViewCommand(string viewName) {
#if false
return new RelayCommand(() => {
Debug.WriteLine("It fired.");
Navigation.Navigate(ServiceLocator.Current.GetInstance<IViewLocator>().GetViewForNavigation("StudentPage2"));
});
#else
return new RelayCommand(() => {
Debug.WriteLine("It fired.");
Navigation.Navigate(ServiceLocator.Current.GetInstance<IViewLocator>().GetViewForNavigation(viewName));
});
#endif
}
如果我对
viewName
的执行委托(delegate)中的方法使用RelayCommand
参数,则不会触发。我将此命令绑定(bind)到一个按钮。当我单击该按钮时,连Debug.WriteLine
命令都不会触发(并且放置在其上的断点不会中断)。但是,如果我用与
viewName
中的值相同的硬编码字符串替换viewName
参数,则RelayCommand
可以正常工作。请注意,此代码(未在按钮中使用该命令)执行时不会出现问题:
void Test() {
Command1.Execute(null);
Command2("David").Execute(null);
}
RelayCommand Command1 { get { return new RelayCommand(() => Debug.WriteLine("cmd1 executed.")); } }
RelayCommand Command2(string msg) { return new RelayCommand(() => Debug.WriteLine("cmd2 executed: " + msg)); }
但是,如果我在Xaml中将
Command2
绑定(bind)到Button.Command
,它将无法执行:public ICommand TestCommand2 { get { return Command2("Cater"); } }
<Button Grid.Row="1" Grid.Column="1" Command="{Binding TestCommand2}" Content="TEST" />
任何想法可能在这里发生什么?
更新
进一步的实验表明,在Execute委托(delegate)中使用虚拟属性代替参数似乎确实可行。当绑定(bind)到button.Command时,由
NavigateToViewCommand
在此代码中创建的命令可以正常工作。当然,那并不能解决问题。这只是更多信息。// In base class:
protected RelayCommand NavigateToViewCommand() {
return new RelayCommand(() => Navigation.Navigate(ServiceLocator.Current.GetInstance<IViewLocator>().GetViewForNavigation(NextPageViewName)));
}
protected virtual string NextPageViewName { get { return string.Empty; } }
// In subclass:
private ICommand m_nextPage;
public ICommand NextPageCommand { get { return m_nextPage ?? (m_nextPage = NavigateToViewCommand()); } }
protected override string NextPageViewName { get { return "StudentPage2"; } }
最佳答案
我更喜欢使用内置的ICommand
模式,而不是将此参数传递给RelayCommand
ctor,这意味着:
protected RelayCommand NavigateToViewCommand()
{
return new RelayCommand((viewName) => {
Debug.WriteLine("It fired.");
Navigation.Navigate(ServiceLocator.Current
.GetInstance<IViewLocator>()
.GetViewForNavigation(viewName.ToString()));
});
}
并像下面这样调用execute:
NavigateToViewCommand().Execute("David");
这是将参数传递给命令的一种更为温和的方法。
ps:我没有尝试过。我希望它没有错字,并且工作正常。