Source: WPF Accordion Control Source
WPF does not contain an out of the box accordion control, but it does provide an expander control.
Since an accordion control is nothing more than a stack of expanders it is very easy to build one ourselves.
This shows just a basic control, Feel free to pimp the control with a custom template or extend it with your functionality.
First create a WPF Custom control library.
Then add a "Custom Control (WPF)" item to the project and name it "Accordion.cs"
Add the following code into this file:
Note: As you can see, the Accordion control is just a custom stackpanel with functionality to expand/collapse the expanders within the stackpanel.
namespace WpfDemoControlLibrary
{
public class Accordion : StackPanel
{
static Accordion()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Accordion),
new FrameworkPropertyMetadata(typeof(Accordion)));
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.InitializeAccordion();
}
protected void InitializeAccordion()
{
Expander selectedExpander;
foreach (UIElement element in this.Children)
{
selectedExpander = element as Expander;
if (selectedExpander != null)
{
selectedExpander.Expanded += new RoutedEventHandler(selectedExpander_Expanded);
}
}
}
void selectedExpander_Expanded(object sender, RoutedEventArgs e)
{
Expander selectedExpander = sender as Expander;
Expander otherExpander = null;
ContentPresenter contentPresenter = null;
double totalExpanderHeight = 0;
if (selectedExpander != null)
{
foreach (UIElement element in this.Children)
{
otherExpander = element as Expander;
if (otherExpander != null & otherExpander != selectedExpander)
{
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 = this.ActualHeight - totalExpanderHeight - selectedExpander.ActualHeight;
}
}
}
}
}
When the prior file was created it added a section to the Theme\General.xaml file.
Make sure it reflects the following line:
<Style TargetType="{x:Type local:Accordion}"></Style>
By adding the following line to the "Properties\AssemblyInfo.cs" file, the control can later be referenced by your personal namespace.
[assembly: XmlnsDefinition("http://schemas.rooijakkers.net/presentation", "WpfDemoControlLibrary")]
Now, Create a test WPF application that references the created control library.
Note: Make sure that you add the previously defined namespace to the top of the window.
That's it.