I am attempting to create an MVVM Light RelayCommand
in a method:
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
}
If I use the viewName
parameter to the method in the Execute delegate for the RelayCommand
, it will not fire. I am binding this command to a button. When I click the button, not even the Debug.WriteLine
command fires (and a breakpoint placed on it won't break).
However, if I replace the viewName
parameter with a hard-coded string that is the same as the value in viewName
, the RelayCommand
works fine.
Note that this code, where the command isn't used in a button executes without a problem:
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)); }
But if I bind Command2
to Button.Command
in Xaml, it doesn't execute:
public ICommand TestCommand2 { get { return Command2("Cater"); } }
<Button Grid.Row="1" Grid.Column="1" Command="{Binding TestCommand2}" Content="TEST" />
Any ideas what might be going on here?
UPDATE
Further experimentation shows that using a virtual property in the Execute delegate instead of a parameter does appear to work. The command created by NavigateToViewCommand
in this code works fine when bound to button.Command. That doesn't resolve the issue, of course; this is just more information.
// 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"; } }
I prefered to use in-built ICommand
pattern instead of this parameter passing to RelayCommand
ctor , which means:
protected RelayCommand NavigateToViewCommand()
{
return new RelayCommand((viewName) => {
Debug.WriteLine("It fired.");
Navigation.Navigate(ServiceLocator.Current
.GetInstance<IViewLocator>()
.GetViewForNavigation(viewName.ToString()));
});
}
and call execute like this:
NavigateToViewCommand().Execute("David");
It's a more gentle way to pass arguments to your command. ps.: I did not try this. I hope it has no typo and it's working fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.