Ricardo Seixas
Ricardo Seixas

Reputation: 31

Dynamically add child expander

Is there a way to create child expanders like this xaml bellow, at run-time?

<Expander Header="Building" IsExpanded="True">
    <StackPanel>
        <Expander Header="Sales">
            <StackPanel>
                <TextBlock>6100</TextBlock>
                <TextBlock>6101</TextBlock>
                <TextBlock>6111</TextBlock>
                <TextBlock>6150</TextBlock>
            </StackPanel>
        </Expander>
        <Expander Header="Director">
            <StackPanel>
                <TextBlock>6102</TextBlock>
                <TextBlock>6113</TextBlock>
            </StackPanel>
        </Expander>
    </StackPanel>
</Expander>

Upvotes: 2

Views: 9087

Answers (3)

Eli Arbel
Eli Arbel

Reputation: 22739

The best way would probably be to use data binding. I'm assuming you have some data structure that describes which expanders you want to create. Let's assume we have:

class Building
{
    public List<Item> Items { get; }
    public string Name { get; }
}

class Item
{
    public int Number { get; }
}

In our user control, we'll set the DataContext to a list of Buildings (e.g. in the constructor):

DataContext = GetListOfBuildings();

Then we'd use two nested ItemsControls with templates to create the controls at runtime:

<Expander Header="Building"
          IsExpanded="True">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}">
                    <ItemsControl ItemsSource="{Binding Items}"
                                  DisplayMemberPath="Number" />
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Expander>

This way you would not need to create controls in C#, which is more cumbersome in WPF.

Upvotes: 1

Parham.D
Parham.D

Reputation: 1168

Set a name for first StackPanel (MainStackPanel) under the top Expander.

// Add new expander, stack panel and text block.
var newExpander = new Expander {Name = "NewExpander", Header = "New Expander"};
var newstackPanel = new StackPanel {Name = "NewExpanderStackPanel"};
var newtextBlock = new TextBlock {Text = "777"};

// Add above items as children.     
newstackPanel.Children.Add(newtextBlock);
newExpander.Content = newstackPanel;
MainStackPanel.Children.Add(newExpander);

Upvotes: 5

Charles Liu
Charles Liu

Reputation: 11

Not quite sure about what you want to achieve.

If I understand correctly, you can save your code in a .xaml file as resource and use application to load it. Then, add the object to the visual tree.

  var expander = (Expander) Application.LoadComponent(new Uri("UriToTheXamlFile"));
  control.AddChild(expander);

Upvotes: 0

Related Questions