MVVM List Detail pattern
code
ListDetail
https://github.com/mikihiro-t/MVVMPattern
Until now, I wrote List and Detail each time by trial and error, so I tried to summarize them in a pattern.
Development environment
Build with .NET Core 3.1 + ReactiveProperty.
ListViewModel and DetailViewModel

ListViewModel.cs
this.InfoList = this.Model.InfoList.ToReadOnlyReactiveCollection(x => new DetailViewModel(x)).AddTo(Disposable);
So, ** create each DetailViewModel corresponding to each row of the DataGrid **.
When I first started learning MVVM, I didn’t know how to do this with DataGrid or ListView.
Show
The XAML for the Show button is:
Command calls the DataContext of the DataGrid, that is, the ButtonShow of the DataContext (= ListViewModel) of the Window.
The parameter becomes the DetailViewModel on this line by CommandParameter = "{Binding}" .
ListView.xaml
<Button Command="{Binding DataContext.ButtonShow, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding}">Show</Button>
ListViewModel.cs
public ReactiveCommand<DetailViewModel> ButtonShow { get; } = new ReactiveCommand<DetailViewModel>();
** Receive the DetailViewModel itself in that line as a parameter ** (where x is the parameter)
ListViewModel.cs
ButtonShow.Subscribe(x => ShowDetail(x)).AddTo(Disposable);
private void ShowDetail(DetailViewModel infoVM)
{
Model.ShowDetail(infoVM.Model);
}
Pass the Model (infoVM.Model) held by the DetailViewModel to the ListManager to display the Detail.
Therefore, the Model refers to the same thing in both the Row and Detail of the DataGrid, but the VMs are different.

If you want to display Detail using the same DetailViewModel used in the row of DataGrid,
ListViewModel.cs
private void ShowDetail(DetailViewModel infoVM)
At the stage of, you may use infoVM to display DetailView from ListViewModel.cs. Then the row in the DataGrid and the DataContext in the newly displayed DetailView will use the same DetailViewModel.
Remove
It’s almost the same as Show.
new order
New in the order of Model → ViewModel → View.
Main.cs
var list = new ListManager();
ViewController.ShowListView(list);
I decided to handle the new of View and ViewModel in the public static class of ViewController.
ViewController.cs
public static void ShowListView(ListManager model)
{
var viewModel = new ListViewModel(model);
var view = new ListView(viewModel);
view.Show();
}
There is also a method of View → ViewModel → Model, but here Model comes first.
If the Model is running in the background and you want to display the View under certain conditions, you will have to put the Model first, and it is hard to think that there is no Model and only V and VM in MVVM, so Model first The idea is that it’s better to do new.
Dispose timing
What I don’t understand about ReactiveProperty is when to call Dispose.
DataGrid ViewModel

Clear / Remove of DataGrid is Clear or Remove of ʻObservableCollection
Detail ViewModel

When DetailView is Close, it is not known whether it will be Dispose, so it is ** explicitly Dipose **.
DetailViewModel.cs
private void Close()
{
CloseAction();
Dispose();
}
Impressions
The flow of processing is not clear, and unless you follow it while debugging, you can not understand it just by looking at the code. I think this is the difficult part of MVVM.
However, if you pattern it, it will be a little easier to get an idea of the processing flow.
MVVM article
- Pattern 1 View code behind
- Pattern 2 Command parameter
- Pattern 3 Prism Dialog Service