WPF: View with Multiple SubViews

75 views Asked by At

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.

2

There are 2 answers

0
BionicCode On BEST ANSWER

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

0
Clemens On

The most basic control to display a dynamic collection of view elements is the ItemsControl.

With your view model, you would write something like shown below, where your ChildView is declared in the ItemTemplate. The DataContext of each ChildView is automatically assigned to the respective element of the Children collection.

<ItemsControl ItemsSource="{Binding Children}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <views:ChildView/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The default Panel used by an ItemsControl is a vertical StackPanel. You can change that by setting the ItemsPanel property to an ItemsPanelTemplate with a different Panel. Typical Panels are horizontal StackPanel, WrapPanel and UniformGrid. A Grid is also possible, but you would need to have view model properties for the row and column of each item.

<ItemsControl ItemsSource="{Binding Children}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <views:ChildView/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>