Search code examples
wpfmvvmuser-controls

WPF: View with Multiple SubViews


I'm trying to put together a control in WPF that has children views.
The number of child views (can grow or shirk) from 1-10. And I would like the main view to show that.
If possible I would like to avoid having to hard code each view in to the xaml file. Instead I would like that to be dynamic. I'm following the MVVM pattern, and I would like the number of views to correspond to the number of children view models in the parent's view model.

The view models look similar too (I've simplified the code)

    public class ParentViewModel : ObservableObject
    {
        public List<ChildViewModel> Children { get; set; }
    }

    public class ChildViewModel
    { 
    }

The xaml that I would like to try to avoid:

    <Grid>

        <views:ChildView DataContext ="{Binding Children[0]}"/>
        <views:ChildView DataContext ="{Binding Children[1]}"/>
        <views:ChildView DataContext ="{Binding Children[2]}"/>
        ... ect 

    </Grid>

I know that some other controls in wpf have an ItemsSource that you can bind the list to in the ViewModels.
I'm just unsure of what that would look like and am struggling to find examples.


Solution

  • You can always use a ListBox to present a list of objects. The ItemTemplate proerty defines how the data items are actually rendered:

    <ListBox ItemsSource="{Binding Children}">
    
      <!-- Only use the following ItemContainerStyle to remove the listbox look and feel -->
      <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType=ListBoxItem">
                <ContentPresenter />
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </ListBox.ItemContainerStyle>
      
      <ListBox.ItemTemplate>
        <DataTemplate DataType="ChildViewModel">
          <views:ChildView />
        </DataContext>
      </ListBox.ItemTemplate>
    </ListBox>
    

    Microsoft learn: Data Templating Overview