Search code examples
c#mvvmexpander

How to add Expanders to View from ViewModel in C#?


I try to add expander elements dynamically from my ViewModel to my View. This is my view model using Prism' Bindable base:

public class MyViewModel : BindableBase
    {
        public MyViewModel()
        {
            MyExpanders = new List<Expander>();
            AddAllExpanders();
        }

        private void AddAllExpanders()
        {
            AddExpander("First expander header", "First expander content");
            AddExpander("Second expander header", "Second expander content");
        }

        private void AddExpander(string header, string content)
        {
            var expander = new Expander();
            expander.Header = header;
            expander.HorizontalAlignment = HorizontalAlignment.Stretch;
            expander.Margin = new Thickness(10);
            expander.Background = Brushes.LightGray;
            expander.IsExpanded = false;
            expander.Content = content;
            MyExpanders.Add(expander);
        }

        private List<Expander> _myExpanders;
        public List<Expander> MyExpanders
        {
            get { return _myExpanders; }
            set { SetProperty(ref _myExpanders, value); }
        }
    }

and this is my view:

<UserControl x:Class="MyProject.Views.MyView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyProject.Views"
             x:Name="Info"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="1">
            <ContentControl Content="{Binding MyExpanders}"/>
        </StackPanel>
    </Grid>
</UserControl>

This only shows "(Sammlung)" which is "collection" in english:

enter image description here

What am I missing?


Solution

  • you need to use ObservableCollection<> rather than a List<> if you want to bind it

    Try this:

        private ObservableCollection<Expander> myExpanders;
    
        public ObservableCollection<Expander> MyExpanders
        {
            get => this.myExpanders;
            set => SetProperty(ref this.myExpanders, value);
        }
    

    In XAML i would accomplish this by using an Itemscontrol:

        <ItemsControl  ItemsSource="{Binding MyExpanders}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>