Ok, so I found WPF MVVM navigate views in which Sheridan does a (mostly) great explanation on how to navigate multiple views in a single window. Following the code and explanation I was able to get the views switching using the code behind, however I can't manage to get his XAML Command=""
version of the view switch working.
I had to search around to find a version of ActionCommand()
that matches his inputs, but I'm not even sure it's the correct one, and I can't find anything on the IsViewModelOfType<T>()
method at all. Which means the final solution given is partially broken.
How do I get that last part working without 3rd party libraries?
Unfortunately because StackOverflow hates new users participating in anything I couldn't just ask in the same thread.
From the above post, this is the part that doesn't work, because the two parts -- ActionCommand and IsViewModelOfType -- don't seem to exist anywhere and there's no information for them searching online
Finally, how do we change the views from other views? Well there are several possible ways to do this, but the easiest way is to add a Binding from the child view directly to an ICommand in the MainViewModel. I use a custom version of the RelayComand, but you can use any type you like and I'm guessing that you'll get the picture:
public ICommand DisplayPersonView { get { return new ActionCommand(action => ViewModel = new PersonViewModel(), canExecute => !IsViewModelOfType<Person>()); } }
In the child view XAML:
<Button Command="{Binding DataContext.DisplayPersonView, RelativeSource= {RelativeSource AncestorType={x:Type MainViewModel}}, Mode=OneWay}" />
Update:
I tried returning both True
and False
from my own IsViewModelOfType<T>()
(as well as actually testing) but to no avail. The key to the problem appears to be either the ActionCommand()
method, for which I have no basis to go on, or that the XAML itself is incorrect.
The closest match I can find for ActionCommand()
is from Microsoft.Expression.Interactivity.Core
but it only accepts a single parameter and doesn't appear to behave correctly for this usage.
I also tried this code snippet I found online, but it doesn't do anything when using Sheridan's code either
class ActionCommand : ICommand
{
private readonly Action<object> _executeHandler;
private readonly Func<object, bool> _canExecuteHandler;
public ActionCommand(Action<object> execute, Func<object, bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("Execute cannot be null");
_executeHandler = execute;
_canExecuteHandler = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_executeHandler(parameter);
}
public bool CanExecute(object parameter)
{
if (_canExecuteHandler == null)
return true;
return _canExecuteHandler(parameter);
}
}