C#: WPF Accordion Usercontrol

10. November 2009

dotnet
Im .net Framework wird leider kein fertiges Accordion Control für WPF mitgeliefert. Dies ist auch nicht weiter schlimm, den ein eigenes kann man sich sehr schnell selber zusammenbauen. Dazu nimmt man als Basis einfach ein StackPanel und fügt diesem als Inhalt Expander Controls hinzu.

public class Accordion : StackPanel
{
  static Accordion()
  {
    DefaultStyleKeyProperty.OverrideMetadata(typeof(Accordion), new FrameworkPropertyMetadata(typeof(Accordion)));
  }
 
  protected override void OnInitialized(System.EventArgs e)
  {
    base.OnInitialized(e);
    InitializeAccordion();
  }
 
  protected void InitializeAccordion()
  {
    Expander selectedExpander;
    foreach(UIElement element in Children)
    {
      selectedExpander = element as Expander;
      if(selectedExpander != null)
        selectedExpander.Expanded += SelectedExpanderExpanded;
    }
  }
 
  public void SelectedExpanderExpanded(object sender, RoutedEventArgs e)
  {
    Expander selectedExpander = sender as Expander;
    Expander otherExpander;
    ContentPresenter contentPresenter;
    double totalExpanderHeight = 0;
 
    if (selectedExpander == null)
      return;
 
    foreach(UIElement element in Children)
    {
      otherExpander = element as Expander;
 
      if (otherExpander == null || otherExpander == selectedExpander)
        continue;
 
      if(otherExpander.IsExpanded)
      {
        contentPresenter = otherExpander.Template.FindName("ExpandSite", otherExpander) as ContentPresenter;
        if (contentPresenter != null)
          totalExpanderHeight -= contentPresenter.ActualHeight;
      }
 
      otherExpander.IsExpanded = false;
      totalExpanderHeight += otherExpander.ActualHeight;
    }
 
    if(selectedExpander.IsExpanded)
    {
      contentPresenter = selectedExpander.Template.FindName("ExpandSite", selectedExpander) as ContentPresenter;
      if (contentPresenter != null)
        contentPresenter.Height = ActualHeight - totalExpanderHeight - selectedExpander.ActualHeight;
    }
  }
}

Im XAML-Code dann einfach das Accordion hinzufügen und als Children-Elemente Expander hinzufügen

<c:Accordion>
  <Expander Header="Inhalt #1">
    <Grid />
  </Expander>
  <Expander header="Inhalt #2">
    <Grid />
  </Expander>
</c:accordion>

Schreib einen Kommentar

Previous post:

Next post: