patterncsharpMinor
MVVM Navigation WPF
Viewed 0 times
wpfnavigationmvvm
Problem
Currently, I'm trying to learn every aspect of the MVVM design pattern.
So basically I've written a little WPF App where I'm trying to understand Navigation in MVVM, the app has one MainView wich controls with a ContentControl the other Views.
Even tho I've read so many things about MVVM I'm never comfortable with my Code, my code works fine but a little voice in my head keeps saying that I'm doing MVVM completely wrong. I spend so much time reading about MVVM because I really don't want to break the pattern.
Starting the Application and loading the ApplicationModel
MainView.xaml
MainView.cs
MainViewModel.cs
```
public class MainViewModel : BaseViewModel {
public MainViewModel(ApplicationModel applicationModel) {
ApplicationModel = applicationModel;
Initialize();
}
private ApplicationModel _applicationModel;
private UserControl _contentWindow;
private string _selectedItem;
private DownloadService _downloadService;
private
So basically I've written a little WPF App where I'm trying to understand Navigation in MVVM, the app has one MainView wich controls with a ContentControl the other Views.
Even tho I've read so many things about MVVM I'm never comfortable with my Code, my code works fine but a little voice in my head keeps saying that I'm doing MVVM completely wrong. I spend so much time reading about MVVM because I really don't want to break the pattern.
Starting the Application and loading the ApplicationModel
public partial class App {
private void App_OnStartup(object sender, StartupEventArgs e) {
ApplicationService.InitializeApplicationDirectorys();
var applicationModel = ApplicationService.LoadApplicationModel() ??
new ApplicationModel {
Settings = new SettingsModel {
WindowHeight = 350,
WindowLeft = 100,
WindowTop = 100,
WindowWidth = 500
}
};
var mainView = new MainView(applicationModel);
mainView.Show();
}
}MainView.xaml
MainView.cs
public partial class MainView {
public MainView(ApplicationModel applicationModel) {
InitializeComponent();
DataContext = new MainViewModel(applicationModel);
}
}MainViewModel.cs
```
public class MainViewModel : BaseViewModel {
public MainViewModel(ApplicationModel applicationModel) {
ApplicationModel = applicationModel;
Initialize();
}
private ApplicationModel _applicationModel;
private UserControl _contentWindow;
private string _selectedItem;
private DownloadService _downloadService;
private
Solution
One of the basic principals of MVVM is, that the view model doesn't know the view. My experience is, that this principal can be (and should be) applied for the most cases. However, it is possible that complex views or third party controls, where some functions are not conform to MVVM, require lots of boilerplate code to make it MVVM conform. IMHO that cases legitimize to break the pattern.
But now to your code...
Actually, it is not so far away from the MVVM way to implement such a navigation. You are working with a
Normally, the
In your case, you can just create a
In a second step, you can define the visual representations of the view models by associating the view model's type with a view. That can be done in the
For Example:
Note that there is no need to pass the view model to the view's constructor because it is automatically bound to the view's data context.
But now to your code...
Actually, it is not so far away from the MVVM way to implement such a navigation. You are working with a
ContentWindow property that changes depending on the selected item. That mechanism is OK, but the view model exposes the views directly.Normally, the
MainViewModel would expose another (child) view model that will be represented by a view.In your case, you can just create a
DownloadViewModel, a SettingsViewModel and a HomeViewModel and return the instance of the view models instead of the views.In a second step, you can define the visual representations of the view models by associating the view model's type with a view. That can be done in the
ResourcesDictionary of the ContentControl via data templates.For Example:
...
Note that there is no need to pass the view model to the view's constructor because it is automatically bound to the view's data context.
Code Snippets
<ContentControl Content="{Binding ContentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModels:DownloadViewModel}">
<DownloadView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:SettingsViewModel}">
<SettingsView />
</DataTemplate>
...
</ContentControl.Resources>
</ContentControl>Context
StackExchange Code Review Q#153171, answer score: 5
Revisions (0)
No revisions yet.