Reputation: 23
I am using Caliburn.Micro 3 in my MVVM WPF Application. I succesfully managed to implement navigation in my app by following the documentation and the samples provided.
However, I want to follow the SOLID principles and I think that using a ShellViewModel as a Conductor is a violation of the single responsibility principle.
In order to resolve this problem I created a "service" which control my navigation but I can't manage to display the ActiveItem. When I navigate, I have the ViewModel name as a string instead of the View associated with it.
public class NavigationService : Conductor<IScreen>, INavigationService
{
public void GoTo<T>() where T : IScreen
{
var viewModel = IoC.Get<T>();
ActivateItem(viewModel);
}
}
And I use it from my "ShellViewModel".
public class ShellViewModel : PropertyChangedBase
{
private readonly INavigationService _navigationService;
public HomeViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
public INavigationService NavigationService => _navigationService;
public void ShowChartPage() => _navigationService.GoTo<TimeSeriesViewModel>();
}
The ContentControl from my ShellView :
<ContentControl Content="{Binding NavigationService.ActiveItem}" />
Am I missing something ?
Upvotes: 2
Views: 2378
Reputation: 5666
The problem which causes you issue regards your XAML snippet: you are binding the Content
property directly to your ViewModel (TimeSeriesViewModel
), then your application cannot work as you wish. In this situation you will see just a string which represents the type of the object that you are binding to the ContentControl
.
To make you application work correctly you have to use:
ContentControl
in a proper way, so Caliburn can create automatically a binding for you.View.Model
.Both these approaches retrieve the right View for the ViewModel that your infer in the ActiveItem property of your Conductor
.
In the first case your can use <ContentControl x:Name="ActiveItem" />
(but you need to create the corresponding property in the ShellViewModel
class); with the second approach you can use <ContentControl cal:View.Model="{Binding NavigationService.ActiveItem}" /
>.
I hope that my hint and my quick explanation can help you.
Upvotes: 1