I have 3 classes:
public class ViewModelA
{
public ObservableCollection<ViewModelB> GroupsB { get; set; }
}
public class ViewModelB
{
public ObservableCollection<ViewModelC> GroupsC { get; set; }
}
public class ViewModelC
{
public string Name { get; set; }
}
And a ListView
which shows all ViewModelC
objects of all ViewModelB
objects:
<ListView ItemsSource={Binding DataContext.GroupsB.GroupsC, ElementName=MyWindow}>
<ListView.View>
<DataGridView>
<DataGridView.Columns>
<DataGridViewColumn Header="Name" DisplayMemberPath="{Binding Name}" />
</DataGridView.Columns>
</DataGridView>
</ListView.View>
</ListView>
where MyWindow
is the name of Window
:
<Window.DataContext>
<vm:ViewModelA />
</Window.DataContext>
The Window
has the event Loaded
which used to create sample:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ViewModelA obj = new();
// some statements to initialize obj
obj.GroupsB = new();
for (int i = 0; i < 3; i += 1)
{
ViewModelB b = new();
for (int j = 0; j < 5; j += 1)
{
ViewModelC c = new ViewModelC { Name = $"B: {i}, C: {j}" };
b.GroupsC.Add(c);
}
obj.GroupsC.Add(b);
}
this.DataContext = obj;
}
The expected result is that the ListView
displays all ViewModelC
objects as shown:
// Total 15 rows:
// B: 0, C: 0
// B: 0, C: 1
// B: 0, C: 2
// ...
// B: 1, C: 0
// B: 1, C: 1
// B: 1, C: 2
// ...
// B: 3, C: 2
// B: 3, C: 3
// B: 3, C: 4
However, the actual result is that the ListView
displays nothing.
Programmatically, we can solve this by:
List<ViewModelC> list = new();
foreach (ViewModelB b in obj.GroupsB)
{
list.AddRange(b.GroupsC);
}
listView.ItemsSource = new ObservableCollection<ViewModelC>(list);
But what if insists to use MVVM pattern? Can anyone suggest me some corrections?