Search code examples
wpftemplatesrecursiondatatemplate

WPF C# Expander menu from tree list


Rather than a treeview menu we want a menu to look like the accordion style with animated collapse/expand nested sections. Initially I did assign my list to a treeview & the tree is drawn correctly so next I managed to prototype the accordion style (using https://www.codeproject.com/Articles/248112/Templating-WPF-Expander-Control) but now I want to create the menu dynamically using the list used for the tree. I'm new to WPF so doing it the right way by binding my tree-like list to a view is more daunting to me so I set off creating the Expander and Stackpanels in c#. I got stuck assigning the Template to the expander. My partial xaml.cs code:

    private void CreateMenu(PageViewModel n)
    {
        doRecurseTree(n, MenuStack);
    }

    private void doRecurseTree(PageViewModel n, StackPanel sp)
    {
        foreach (PageViewModel c in n.Children)
        {
            if (c.Children.Count() > 0)
            {
                Console.WriteLine("<expander header='"+c.Name+"'><stackpanel>");

                Expander ex = new Expander();
                ex.OverridesDefaultStyle = true;
                ex.Header = c.Name;
                ex.HorizontalAlignment = HorizontalAlignment.Left;
                ex.VerticalAlignment = VerticalAlignment.Top;
                ex.Template = /*"{StaticResource RevealExpanderTemp}"*/;

                StackPanel spc = new StackPanel();


                doRecurseTree(c, spc);
                Console.WriteLine("</stackpanel></expander>");
            }
            else
            {
                Console.WriteLine("<button content='" + c.Name+"' />");
                Button b = new Button();
                b.Content = c.Name;
                sp.Children.Add(b);
            }
        }

    }

The xaml in my prototype looks like this:

          <Expander Template="{StaticResource RevealExpanderTemp}"
          OverridesDefaultStyle="True"
          Header="Option 1"
          HorizontalAlignment="Left"
          VerticalAlignment="Top"
          >
            <StackPanel>
              <Expander Template="{StaticResource RevealExpanderTemp}"
              OverridesDefaultStyle="True"
              Header="Sub Option 1"
              HorizontalAlignment="Left"
              VerticalAlignment="Top"
              >
                    <StackPanel>
                            <Button  Content="Item 1.1" Style="{StaticResource TestContentStyle}"/>
                            <Button  Content="Item 1.2" Style="{StaticResource TestContentStyle}"/>
                            <Button Content="Item 1.3" Style="{StaticResource TestContentStyle}"/>
                            <Button Content="Item 1.4" Style="{StaticResource TestContentStyle}"/>
                    </StackPanel>
              </Expander>

              <Expander Template="{StaticResource RevealExpanderTemp}"
              OverridesDefaultStyle="True"
              Header="Sub Option 2"
              ...

Ideas on how to assign the Template in C# or do the solution in the view are very welcome.

Thanks in advance, Steve


Solution

  • Well, I solved the template style problem with ease after more searching. You have to lookup the style and apply it thus:

    ex.Template = (ControlTemplate)FindResource("RevealExpanderTemp");