
Syncfusion Maui Toolkit Accordion
- 1 installs
- 39 repo stars
- Updated June 19, 2026
- syncfusion/maui-toolkit-ui-components-skills
Syncfusion MAUI Toolkit Accordion is an agent skill that guides AutoScrollPosition and scrolling behavior for Syncfusion SfAccordion in .NET MAUI apps.
About
Syncfusion MAUI Toolkit Accordion is an agent skill for developers shipping.NET MAUI apps who need collapsible sections that behave predictably on expand. It focuses on advanced SfAccordion features: AutoScrollPosition (MakeVisible, Top, None), programmatic scrolling after expansion, and layout choices for long forms or FAQ content. The skill helps you choose MakeVisible when you want minimal scroll disruption versus Top when users should always read expanded content from the viewport top. It is phase-specific to Build frontend mobile work—not a full app scaffold, but targeted procedural knowledge for one high-friction UI control. Pair it when you already use Syncfusion MAUI Toolkit and want your agent to generate correct XAML and C# without guessing scroll semantics. Beginner-friendly if you know MAUI basics; no server or CRM dependencies.
- AutoScrollPosition: MakeVisible, Top, and None modes documented
- Programmatic scrolling and layout guidance for long accordion sections
- XAML and C# configuration examples for SfAccordion
- When-to-use guidance for minimal vs top-aligned expand scroll
- Advanced accordion behavior beyond default MakeVisible
Syncfusion Maui Toolkit Accordion by the numbers
- 1 all-time installs (skills.sh)
- Ranked #959 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Jul 7, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/maui-toolkit-ui-components-skills --skill syncfusion-maui-toolkit-accordionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 39 |
| Last updated | June 19, 2026 |
| Repository | syncfusion/maui-toolkit-ui-components-skills ↗ |
What it does
Configure Syncfusion.NET MAUI Accordion expand behavior, auto-scroll modes, and layout when building collapsible sections in a MAUI app.
Who is it for?
Best when you're building MAUI apps with Syncfusion and need FAQ, settings, or long-form sections in accordions.
Skip if: Skip if you're on pure SwiftUI or React Native without.NET MAUI—use platform-native UI skills instead.
When should I use this skill?
You are implementing or tuning Syncfusion SfAccordion auto-scroll, programmatic scroll, or layout in a .NET MAUI app.
What you get
Your agent produces SfAccordion markup and C# with the correct AutoScrollPosition mode and scroll rules for your content length and UX goals.
- SfAccordion XAML or C# snippets
- AutoScrollPosition configuration choice with rationale
By the numbers
- 3 AutoScrollPosition options: MakeVisible, Top, None
Files
Implementing Syncfusion .NET MAUI Accordion
A comprehensive guide for implementing the Syncfusion .NET MAUI Accordion (SfAccordion) - a vertically collapsible panel control that allows users to expand or collapse one or multiple items simultaneously.
When to Use This Skill
Use this skill when you need to:
- Implement collapsible/expandable content sections in .NET MAUI
- Display employee directories, contact lists, or detailed records
- Create FAQ sections with expandable answers
- Build settings panels with grouped options
- Show hierarchical data with expand/collapse behavior
- Implement vertical expander panels
- Bind accordion items to ObservableCollection data sources
- Customize accordion appearance with themes and Visual States
- Handle expansion/collapse events with validation
Component Overview
The .NET MAUI Accordion provides a vertically stacked interface where each item consists of a header and content section. Users can tap headers to expand/collapse content, making it ideal for displaying hierarchical information, FAQs, employee directories, or any scenario requiring space-efficient grouped content display.
- Single or multiple item expansion modes
- Data binding with .NET MAUI BindableLayout
- Customizable animations (duration and easing)
- Rich appearance customization (colors, icons, Visual States)
- Event handling for expand/collapse actions
- Programmatic scroll control
Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation of Syncfusion.Maui.Toolkit NuGet package
- Handler registration with ConfigureSyncfusionToolkit()
- Basic SfAccordion setup in XAML and C#
- Creating AccordionItem with Header and Content
- Expand modes: Single, Multiple, MultipleOrNone
- Animation duration and easing customization
- Item spacing configuration
- Auto scroll position settings
- BringIntoView method for programmatic scrolling
Data Binding with BindableLayout
📄 Read: references/data-binding.md
- Creating data models with INotifyPropertyChanged
- Setting up ObservableCollection for accordion items
- Configuring BindingContext
- Using BindableLayout.ItemsSource for data binding
- Defining BindableLayout.ItemTemplate for item appearance
- Two-way binding with IsExpanded property
- Dynamic item generation from collections
- Complete employee list example with data binding
Appearance Customization
📄 Read: references/appearance-customization.md
- Header icon position (Start, End)
- Header background color customization
- Icon color customization
- Visual State Manager for state-based styling
- Expanded and Collapsed states
- Focused state for keyboard navigation
- PointerOver state for hover effects
- Normal state styling
- Complete Visual State styling examples
Events and Interaction
📄 Read: references/events.md
- Expanding event (cancellable)
- Expanded event (completion notification)
- Collapsing event (cancellable)
- Collapsed event (completion notification)
- Event arguments: Cancel and Index properties
- Validation before expand/collapse
- Common event handling patterns
Advanced Features
📄 Read: references/advanced-features.md
- Auto scroll position (Top, MakeVisible)
- BringIntoView for programmatic scrolling
- Grid layout considerations with Height=Auto
- HorizontalOptions and VerticalOptions best practices
Advanced Features in .NET MAUI Accordion
This guide covers advanced features of the Syncfusion .NET MAUI Accordion, including auto-scroll positioning, programmatic scrolling and layout considerations.
Auto Scroll Position
The AutoScrollPosition property controls where an expanded accordion item scrolls within the viewport after expansion.
Options:
MakeVisible(Default) - Scrolls just enough to make the item visibleTop- Scrolls the expanded item to the top of the viewportNone- The accordion item does not scrolls and remain in the same position.
MakeVisible Mode
Scrolls the minimum amount needed to bring the item into view. If the item is already fully visible, no scrolling occurs.
When to use:
- Preserve user's current scroll position when possible
- Minimize disorientation from excessive scrolling
- Short accordion items that fit in viewport
<syncfusion:SfAccordion AutoScrollPosition="MakeVisible">
<syncfusion:SfAccordion.Items>
<!-- Items -->
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>accordion.AutoScrollPosition = AccordionAutoScrollPosition.MakeVisible;Top Mode
Always scrolls the expanded item to the top of the viewport, providing a consistent viewing experience.
When to use:
- Long accordion items with extensive content
- Forms or sections where users need to start reading from the top
- Predictable, consistent user experience
<syncfusion:SfAccordion AutoScrollPosition="Top">
<syncfusion:SfAccordion.Items>
<!-- Items -->
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>accordion.AutoScrollPosition = AccordionAutoScrollPosition.Top;Example: FAQ with Long Answers
<syncfusion:SfAccordion AutoScrollPosition="Top">
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="What is .NET MAUI?" Margin="16,14,0,14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="Long answer with multiple paragraphs..."
LineBreakMode="WordWrap" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>Programmatic Scrolling with BringIntoView
The BringIntoView method allows you to programmatically scroll a specific accordion item into view.
Syntax:
accordion.BringIntoView(AccordionItem item);Basic Usage
// Scroll to a specific item by index
private void ScrollToItem(int index)
{
if (index >= 0 && index < accordion.Items.Count)
{
accordion.BringIntoView(accordion.Items[index]);
}
}Use Cases
1. Navigate to First Error:
private void ValidateForm()
{
for (int i = 0; i < accordion.Items.Count; i++)
{
if (!ValidateSection(i))
{
// Scroll to first section with errors
accordion.BringIntoView(accordion.Items[i]);
accordion.Items[i].IsExpanded = true;
break;
}
}
}2. Jump to Section Button:
<StackLayout>
<HorizontalStackLayout Spacing="8" Padding="16">
<Button Text="Jump to Section 1" Clicked="JumpToSection1_Clicked" />
<Button Text="Jump to Section 5" Clicked="JumpToSection5_Clicked" />
<Button Text="Jump to Last" Clicked="JumpToLast_Clicked" />
</HorizontalStackLayout>
<syncfusion:SfAccordion x:Name="accordion">
<!-- 10+ items -->
</syncfusion:SfAccordion>
</StackLayout>private void JumpToSection1_Clicked(object sender, EventArgs e)
{
accordion.BringIntoView(accordion.Items[0]);
}
private void JumpToSection5_Clicked(object sender, EventArgs e)
{
accordion.BringIntoView(accordion.Items[4]);
}
private void JumpToLast_Clicked(object sender, EventArgs e)
{
accordion.BringIntoView(accordion.Items[^1]);
}3. Search Result Navigation:
private void SearchButton_Clicked(object sender, EventArgs e)
{
string query = searchEntry.Text?.ToLower();
if (string.IsNullOrEmpty(query)) return;
for (int i = 0; i < employeeData.Count; i++)
{
if (employeeData[i].Name.ToLower().Contains(query))
{
// Found match - scroll to it and expand
accordion.BringIntoView(accordion.Items[i]);
accordion.Items[i].IsExpanded = true;
break;
}
}
}4. Deep Link Navigation:
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
// Navigate to specific section from query parameter
if (args.Query.TryGetValue("sectionId", out string sectionId))
{
if (int.TryParse(sectionId, out int index) &&
index >= 0 &&
index < accordion.Items.Count)
{
accordion.BringIntoView(accordion.Items[index]);
accordion.Items[index].IsExpanded = true;
}
}
}Grid Layout Considerations
When using SfAccordion inside a Grid with Height="Auto", child elements may not receive height changes at runtime.
Problem:
<!-- ❌ May not size correctly -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<syncfusion:SfAccordion />
</Grid>Solution: Set HorizontalOptions and VerticalOptions to FillAndExpand:
<!-- ✅ Correct -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<syncfusion:SfAccordion HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
</Grid>Why This Happens
The SfAccordion is a template-based control, so its default height cannot be determined when the Grid uses Height="Auto". The FillAndExpand options ensure the control properly responds to layout changes.
Layout Best Practices
1. Use Star-Sized Rows When Possible:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/> <!-- Better for Accordion -->
</Grid.RowDefinitions>
<syncfusion:SfAccordion />
</Grid>2. Specify Minimum Height:
<syncfusion:SfAccordion MinimumHeightRequest="300" />3. Use ScrollView for Long Content:
<ScrollView>
<syncfusion:SfAccordion />
</ScrollView>4. Avoid Nested Auto Heights:
<!-- ❌ Avoid -->
<Grid RowDefinitions="Auto">
<StackLayout>
<syncfusion:SfAccordion />
</StackLayout>
</Grid>
<!-- ✅ Better -->
<Grid RowDefinitions="*">
<syncfusion:SfAccordion VerticalOptions="FillAndExpand" />
</Grid>Performance Optimization
Lazy Loading Content
Load heavy content only when an item expands:
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
var item = accordion.Items[e.Index];
if (item.Tag == null) // First time expanding
{
// Load expensive content
LoadImagesForSection(item);
LoadDataFromDatabase(item);
item.Tag = "loaded";
}
}Virtualization for Large Lists
For 50+ items, consider using CollectionView with a custom template instead of Accordion, or implement pagination.
Dispose Resources on Collapse
private void Accordion_Collapsed(object sender, ExpandedAndCollapsedEventArgs e)
{
var item = accordion.Items[e.Index];
// Dispose of heavy resources
if (item.Content is Grid grid)
{
foreach (var child in grid.Children)
{
if (child is Image image)
{
image.Source = null; // Free memory
}
}
}
}Troubleshooting
Problem: Accordion doesn't resize in Grid Solution: Set HorizontalOptions="FillAndExpand" and VerticalOptions="FillAndExpand"
Problem: BringIntoView doesn't scroll Solution: Ensure the accordion is inside a ScrollView or scrollable container
Problem: Performance issues with many items Solution: Implement lazy loading in Expanded event, dispose resources in Collapsed event
Additional Resources
Appearance Customization for .NET MAUI Accordion
This guide demonstrates how to customize the appearance of the Syncfusion .NET MAUI Accordion, including header styling, icon positioning, colors, and Visual State Manager integration.
Table of Contents
- Overview
- Header Icon Position
- Header Background Color
- Icon Color Customization
- Visual State Manager
- Expanded and Collapsed States
- Focused State
- PointerOver State
- Normal State
- Complete Visual State Example
- Styling Best Practices
Overview
The .NET MAUI Accordion provides extensive customization options for its appearance:
Customizable Elements:
- Header icon position (Start/End)
- Header background color
- Icon color
- Visual states (Expanded, Collapsed, Focused, PointerOver, Normal)
Styling Approaches: 1. Direct Properties - Set properties on individual AccordionItem instances 2. Styles - Define reusable styles for consistent appearance 3. Visual State Manager - Apply state-specific styling automatically
Header Icon Position
Control the position of the expand/collapse icon in the header using HeaderIconPosition.
Options:
End(Default) - Icon appears on the right sideStart- Icon appears on the left side
XAML:
<syncfusion:SfAccordion HeaderIconPosition="Start">
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Settings" Margin="16,14,0,14" FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="Configure your preferences" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>C#:
accordion.HeaderIconPosition = Syncfusion.Maui.Toolkit.Expander.ExpanderIconPosition.Start;Use Cases:
- Start - Left-aligned layouts, RTL languages, or when icon acts as a visual indicator before text
- End - Right-aligned layouts (default), conventional dropdown/expander pattern
Header Background Color
Customize the background color of individual accordion item headers using HeaderBackground.
XAML:
<syncfusion:SfAccordion>
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem HeaderBackground="#6750A4">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Important Section"
Margin="16,14,0,14"
FontSize="14"
TextColor="White" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16" BackgroundColor="#f4f4f4">
<Label Text="This section has a custom header color" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
<syncfusion:AccordionItem HeaderBackground="LightBlue">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Another Section" Margin="16,14,0,14" FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="Different header color" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>C#:
var item = new AccordionItem();
item.HeaderBackground = new SolidColorBrush(Color.FromArgb("#6750A4"));Color Formats:
- Named colors:
"Red","LightBlue" - Hex:
"#6750A4","#FF5733" - RGBA:
Color.FromRgba(103, 80, 164, 255)
Icon Color Customization
Customize the expand/collapse icon color using HeaderIconColor.
XAML:
<syncfusion:SfAccordion>
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem HeaderIconColor="Brown">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48" BackgroundColor="LightYellow">
<Label Text="Custom Icon Color" Margin="16,14,0,14" FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="The icon color is brown" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
<syncfusion:AccordionItem HeaderBackground="#6750A4"
HeaderIconColor="White">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Dark Header with White Icon"
Margin="16,14,0,14"
FontSize="14"
TextColor="White" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="High contrast icon" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>C#:
var item = new AccordionItem();
item.HeaderIconColor = Colors.Brown;Accessibility Tip: Ensure sufficient contrast between icon color and header background for WCAG compliance.
Visual State Manager
The Visual State Manager enables state-based styling that automatically applies when the accordion item changes state.
Available States:
Expanded- Item is expanded (content visible)Collapsed- Item is collapsed (content hidden)Focused- Item has keyboard focusPointerOver- Mouse/pointer is hovering over item (desktop)Normal- Default state (no interaction)
Expanded and Collapsed States
Apply different styling when items are expanded vs. collapsed.
<ContentPage.Resources>
<Style TargetType="syncfusion:AccordionItem">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState Name="Expanded">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#6750A4"/>
<Setter Property="HeaderIconColor" Value="White"/>
</VisualState.Setters>
</VisualState>
<VisualState Name="Collapsed">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#E8DEF8"/>
<Setter Property="HeaderIconColor" Value="#49454F"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
<syncfusion:SfAccordion>
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Dynamic Colors" Margin="16,14,0,14" FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="Header color changes when expanded" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>Result:
- When collapsed: Light purple header with dark icon
- When expanded: Dark purple header with white icon
Focused State
Style items when they receive keyboard focus.
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#FFE5E5"/>
<Setter Property="HeaderIconColor" Value="#CC0000"/>
</VisualState.Setters>
</VisualState>When Applied:
- User navigates with Tab key
- Item receives focus via keyboard interaction
- Improves accessibility for keyboard-only users
PointerOver State
Apply hover effects on desktop platforms.
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#E0E0E0"/>
<Setter Property="HeaderIconColor" Value="#333333"/>
</VisualState.Setters>
</VisualState>When Applied:
- Mouse hovers over accordion item header
- Desktop/pointer-based platforms only
- Provides visual feedback for interactive elements
Normal State
Define the default appearance when no interaction is occurring.
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="White"/>
<Setter Property="HeaderIconColor" Value="Black"/>
</VisualState.Setters>
</VisualState>Complete Visual State Example
Here's a comprehensive example using all five visual states:
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Toolkit.Accordion;assembly=Syncfusion.Maui.Toolkit"
x:Class="AccordionApp.MainPage">
<ContentPage.Resources>
<Style TargetType="syncfusion:AccordionItem">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<!-- Expanded State -->
<VisualState Name="Expanded">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#6750A4"/>
<Setter Property="HeaderIconColor" Value="White"/>
</VisualState.Setters>
</VisualState>
<!-- Collapsed State -->
<VisualState Name="Collapsed">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#E8DEF8"/>
<Setter Property="HeaderIconColor" Value="#49454F"/>
</VisualState.Setters>
</VisualState>
<!-- Focused State (Keyboard Navigation) -->
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#FFC5C5"/>
<Setter Property="HeaderIconColor" Value="#B00020"/>
</VisualState.Setters>
</VisualState>
<!-- PointerOver State (Hover) -->
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="#D6D6D6"/>
<Setter Property="HeaderIconColor" Value="#424242"/>
</VisualState.Setters>
</VisualState>
<!-- Normal State (Default) -->
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="HeaderBackground" Value="White"/>
<Setter Property="HeaderIconColor" Value="Black"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
<syncfusion:SfAccordion ExpandMode="MultipleOrNone" BackgroundColor="#FAFAFA">
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem x:Name="item1" IsExpanded="True">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48" Padding="16,0">
<!-- Bind TextColor to HeaderIconColor for consistency -->
<Label Text="Employee Details"
TextColor="{Binding HeaderIconColor, Source={x:Reference item1}}"
VerticalTextAlignment="Center"
FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16" BackgroundColor="White">
<StackLayout Spacing="8">
<Label Text="Name: Robin Rane" FontSize="14" />
<Label Text="Position: Chairman" FontSize="14" />
<Label Text="Organization: ABC Inc." FontSize="14" />
</StackLayout>
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
<syncfusion:AccordionItem x:Name="item2">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48" Padding="16,0">
<Label Text="Department Information"
TextColor="{Binding HeaderIconColor, Source={x:Reference item2}}"
VerticalTextAlignment="Center"
FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16" BackgroundColor="White">
<Label Text="Department: Operations" FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>
</ContentPage>Behavior:
- Normal - Default white header, black icon
- PointerOver - Gray header when hovering (desktop)
- Focused - Light red header when keyboard-focused
- Collapsed - Light purple header, dark icon
- Expanded - Dark purple header, white icon
Pro Tip: Bind the header Label's TextColor to the HeaderIconColor property to keep text and icon colors synchronized.
Styling Best Practices
1. Define Global Styles in Resources
Place styles in ContentPage.Resources or App.xaml for reusability:
<Application.Resources>
<Style TargetType="syncfusion:AccordionItem">
<!-- Style definition -->
</Style>
</Application.Resources>2. Use Material Design Color Scheme
Follow Material Design 3 guidelines for professional appearance:
- Primary:
#6750A4 - Surface:
#FFFFFF - On-Surface:
#1C1B1F - Surface-Variant:
#E8DEF8
3. Ensure Sufficient Contrast
Maintain WCAG AA contrast ratio (4.5:1 for text):
- Dark text on light backgrounds
- Light text on dark backgrounds
- Test with accessibility tools
4. Consider Platform Differences
- Desktop - PointerOver states are prominent
- Mobile - Focus and touch states matter more
- Accessibility - Focused states critical for keyboard users
5. Test All States
Verify appearance in all five visual states:
- Normal (default)
- PointerOver (mouse hover)
- Focused (keyboard navigation)
- Expanded (content visible)
- Collapsed (content hidden)
6. Use Consistent Spacing
Maintain consistent padding and margins:
<Grid HeightRequest="48" Padding="16,0">
<Label Margin="0" />
</Grid>7. Avoid Overly Bright Colors
Use muted, professional colors for business applications:
- ✅
#6750A4(Material Purple) - ✅
#2196F3(Material Blue) - ❌
#FF00FF(Neon Magenta) - ❌
#00FF00(Bright Green)
Troubleshooting
Problem: Visual States not applying Solution: Ensure the style is defined in Resources and TargetType matches syncfusion:AccordionItem
Problem: Colors not changing on state transitions Solution: Verify all five states are defined, even if some use the same colors
Problem: Text hard to read on colored headers Solution: Adjust text color based on header background for sufficient contrast
Problem: PointerOver not working Solution: PointerOver is desktop-only; test on Windows or macOS, not mobile
Additional Resources
Data Binding with .NET MAUI Accordion
This guide demonstrates how to bind data to the Syncfusion .NET MAUI Accordion using BindableLayout, enabling dynamic accordion item generation from collections.
Table of Contents
- Overview
- Creating the Data Model
- Creating the ViewModel
- Setting the BindingContext
- Binding Data to SfAccordion
- Defining the AccordionItem Template
- Complete Example
- Two-Way Binding with IsExpanded
- Best Practices
Overview
The SfAccordion control utilizes .NET MAUI BindableLayout to bind data collections. This enables you to:
- Dynamically generate accordion items from ObservableCollection
- Bind item properties to data model properties
- Support two-way binding for expansion state
- Update UI automatically when collection changes
Key Properties:
BindableLayout.ItemsSource- The data collectionBindableLayout.ItemTemplate- Defines how each item is renderedAccordionItem.IsExpanded- Controls expansion state (bindable)
Creating the Data Model
Create a data model class that implements INotifyPropertyChanged for two-way binding support.
EmployeeInfo.cs:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace AccordionApp.Models
{
public class EmployeeInfo : INotifyPropertyChanged
{
private string name;
private string image;
private string position;
private string organizationUnit;
private string dateOfBirth;
private string location;
private string phone;
private bool isExpanded;
private string description;
public string Name
{
get => name;
set
{
name = value;
OnPropertyChanged();
}
}
public string Image
{
get => image;
set
{
image = value;
OnPropertyChanged();
}
}
public string Position
{
get => position;
set
{
position = value;
OnPropertyChanged();
}
}
public string OrganizationUnit
{
get => organizationUnit;
set
{
organizationUnit = value;
OnPropertyChanged();
}
}
public string DateOfBirth
{
get => dateOfBirth;
set
{
dateOfBirth = value;
OnPropertyChanged();
}
}
public string Location
{
get => location;
set
{
location = value;
OnPropertyChanged();
}
}
public string Phone
{
get => phone;
set
{
phone = value;
OnPropertyChanged();
}
}
public bool IsExpanded
{
get => isExpanded;
set
{
isExpanded = value;
OnPropertyChanged();
}
}
public string Description
{
get => description;
set
{
description = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}Why INotifyPropertyChanged?
- Enables two-way binding
- UI updates automatically when properties change
- Supports dynamic data updates
Creating the ViewModel
Create a ViewModel with an ObservableCollection to hold the data.
EmployeeViewModel.cs:
using System.Collections.ObjectModel;
using AccordionApp.Models;
namespace AccordionApp.ViewModels
{
public class EmployeeViewModel
{
public ObservableCollection<EmployeeInfo> Employees { get; set; }
public EmployeeViewModel()
{
Employees = new ObservableCollection<EmployeeInfo>
{
new EmployeeInfo
{
Name = "Robin Rane",
Image = "emp_01.png",
Position = "Chairman",
OrganizationUnit = "ABC Inc.",
DateOfBirth = "09/17/1973",
Location = "Boston",
Phone = "(617) 555-1234",
IsExpanded = false,
Description = "Robin Rane, Chairman of ABC Inc., leads with dedication and vision. Under his guidance, the company thrives and continues to make a significant impact in the industry."
},
new EmployeeInfo
{
Name = "Paul Vent",
Image = "emp_02.png",
Position = "General Manager",
OrganizationUnit = "XYZ Corp.",
DateOfBirth = "05/27/1985",
Location = "New York",
Phone = "(212) 555-1234",
IsExpanded = true, // Pre-expanded
Description = "Paul Vent, General Manager of XYZ Corp., oversees daily operations, ensuring the company's success and growth through strategic planning and effective management practices."
},
new EmployeeInfo
{
Name = "Clara Venus",
Image = "emp_03.png",
Position = "Assistant Manager",
OrganizationUnit = "ABC Inc.",
DateOfBirth = "07/22/1988",
Location = "California",
Phone = "(415) 123-4567",
IsExpanded = false,
Description = "Clara Venus, Asst. Manager at ABC Inc., efficiently handles multiple tasks. With her strong skill set and dedication, she contributes significantly to the company's growth and success."
},
new EmployeeInfo
{
Name = "Maria Even",
Image = "emp_04.png",
Position = "Executive Manager",
OrganizationUnit = "XYZ Corp.",
DateOfBirth = "04/16/1970",
Location = "New York",
Phone = "(516) 345-6789",
IsExpanded = false,
Description = "Maria Even, a highly experienced professional, holds the position of Executive Manager at XYZ Corp. She oversees crucial operations, enforcing company policies and practices."
}
};
}
}
}Why ObservableCollection?
- Automatically notifies UI when items are added/removed
- Supports dynamic collection changes
- Required for live data binding
Setting the BindingContext
Set the ViewModel as the page's BindingContext.
XAML:
<ContentPage xmlns:local="clr-namespace:AccordionApp.ViewModels">
<ContentPage.BindingContext>
<local:EmployeeViewModel />
</ContentPage.BindingContext>
<!-- Content -->
</ContentPage>C#:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new EmployeeViewModel();
}
}Binding Data to SfAccordion
Use BindableLayout.ItemsSource to bind the collection to the accordion.
<syncfusion:SfAccordion BindableLayout.ItemsSource="{Binding Employees}">
<!-- ItemTemplate defined next -->
</syncfusion:SfAccordion>C#:
SfAccordion accordion = new SfAccordion();
BindableLayout.SetItemsSource(accordion, viewModel.Employees);Defining the AccordionItem Template
Use BindableLayout.ItemTemplate to define how each data item is rendered.
<syncfusion:SfAccordion BindableLayout.ItemsSource="{Binding Employees}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<syncfusion:AccordionItem IsExpanded="{Binding IsExpanded}">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="{Binding Name}"
Margin="16,14,0,14"
CharacterSpacing="0.25"
FontFamily="Roboto-Regular"
FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid BackgroundColor="#f4f4f4" Padding="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="Position: " Grid.Row="0" Grid.Column="0" FontSize="14" />
<Label Text="{Binding Position}" Grid.Row="0" Grid.Column="1" FontSize="14" />
<Label Text="Organization: " Grid.Row="1" Grid.Column="0" FontSize="14" />
<Label Text="{Binding OrganizationUnit}" Grid.Row="1" Grid.Column="1" FontSize="14" />
<Label Text="Date of Birth: " Grid.Row="2" Grid.Column="0" FontSize="14" />
<Label Text="{Binding DateOfBirth}" Grid.Row="2" Grid.Column="1" FontSize="14" />
<Label Text="Location: " Grid.Row="3" Grid.Column="0" FontSize="14" />
<Label Text="{Binding Location}" Grid.Row="3" Grid.Column="1" FontSize="14" />
<Label Text="Phone: " Grid.Row="4" Grid.Column="0" FontSize="14" />
<Label Text="{Binding Phone}" Grid.Row="4" Grid.Column="1" FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</DataTemplate>
</BindableLayout.ItemTemplate>
</syncfusion:SfAccordion>Key Bindings:
IsExpanded="{Binding IsExpanded}"- Two-way binding for expansion stateText="{Binding Name}"- One-way binding for header text- All content fields bound to respective properties
Complete Example
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Toolkit.Accordion;assembly=Syncfusion.Maui.Toolkit"
xmlns:local="clr-namespace:AccordionApp.ViewModels"
x:Class="AccordionApp.MainPage">
<ContentPage.BindingContext>
<local:EmployeeViewModel />
</ContentPage.BindingContext>
<syncfusion:SfAccordion ExpandMode="Single"
BindableLayout.ItemsSource="{Binding Employees}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<syncfusion:AccordionItem IsExpanded="{Binding IsExpanded}">
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48" BackgroundColor="White">
<Label Text="{Binding Name}"
Margin="16,14,0,14"
FontSize="14"
VerticalTextAlignment="Center" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid BackgroundColor="#f4f4f4" Padding="16">
<StackLayout Spacing="8">
<Label Text="{Binding Position, StringFormat='Position: {0}'}" FontSize="14" />
<Label Text="{Binding OrganizationUnit, StringFormat='Organization: {0}'}" FontSize="14" />
<Label Text="{Binding DateOfBirth, StringFormat='Date of Birth: {0}'}" FontSize="14" />
<Label Text="{Binding Location, StringFormat='Location: {0}'}" FontSize="14" />
<Label Text="{Binding Phone, StringFormat='Phone: {0}'}" FontSize="14" />
<Label Text="{Binding Description}"
LineBreakMode="WordWrap"
FontSize="13"
Margin="0,8,0,0" />
</StackLayout>
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</DataTemplate>
</BindableLayout.ItemTemplate>
</syncfusion:SfAccordion>
</ContentPage>Two-Way Binding with IsExpanded
The IsExpanded property supports two-way binding, allowing you to:
- Pre-expand specific items by setting
IsExpanded = truein the model - Track expansion state changes in your ViewModel
- Programmatically expand/collapse items
Example: Programmatic Expansion
// In ViewModel
public void ExpandFirstEmployee()
{
if (Employees.Count > 0)
{
Employees[0].IsExpanded = true;
}
}
public void CollapseAll()
{
foreach (var employee in Employees)
{
employee.IsExpanded = false;
}
}Example: Tracking Expansion State
// In Model
private bool isExpanded;
public bool IsExpanded
{
get => isExpanded;
set
{
isExpanded = value;
OnPropertyChanged();
// Log or handle expansion state change
Debug.WriteLine($"{Name} is now {(value ? "expanded" : "collapsed")}");
}
}Best Practices
1. Always Implement INotifyPropertyChanged
Ensures UI updates when data changes.
2. Use ObservableCollection for Dynamic Data
Enables automatic UI updates when items are added/removed.
3. Wrap Labels in Containers
Never use Label directly as Header/Content - always wrap in Grid or other container.
4. Optimize Large Lists
For large datasets (100+ items), consider:
- Virtualizing content (load on expand)
- Lazy loading images
- Pagination or infinite scroll
5. Handle Null Values
Use null-conditional operators and fallback values:
<Label Text="{Binding Phone, TargetNullValue='N/A'}" />6. Use StringFormat for Simple Formatting
<Label Text="{Binding Salary, StringFormat='${0:N2}'}" />Troubleshooting
Problem: Items don't update when data changes Solution: Ensure model implements INotifyPropertyChanged and OnPropertyChanged() is called in property setters
Problem: Adding/removing items doesn't update UI Solution: Use ObservableCollection<T> instead of List<T>
Problem: Binding errors in output Solution: Verify property names match exactly (case-sensitive) between model and bindings
Problem: IsExpanded binding doesn't work Solution: Ensure IsExpanded property in model implements INotifyPropertyChanged and is a bool type
Additional Resources
Events in .NET MAUI Accordion
This guide covers the four built-in events in the Syncfusion .NET MAUI Accordion, enabling you to respond to user interactions and control expansion/collapse behavior.
Overview
The SfAccordion control provides four events for handling accordion item state changes:
| Event | Timing | Cancellable | Use Case |
|---|---|---|---|
| Expanding | Before expansion begins | ✅ Yes | Validate before expanding, prevent expansion |
| Expanded | After expansion completes | ❌ No | Track expansion, load data, analytics |
| Collapsing | Before collapse begins | ✅ Yes | Validate before collapsing, prevent collapse |
| Collapsed | After collapse completes | ❌ No | Track collapse, clean up resources |
Common Event Arguments:
Index- The index of the affected accordion itemCancel- Boolean to prevent the action (Expanding/Collapsing only)
Expanding Event
The Expanding event fires before an accordion item begins to expand. You can cancel the expansion by setting e.Cancel = true.
Event Signature:
public event EventHandler<ExpandingAndCollapsingEventArgs> Expanding;EventArgs Properties:
Index(int) - The zero-based index of the item being expandedCancel(bool) - Set totrueto cancel expansion
Basic Usage
XAML:
<syncfusion:SfAccordion x:Name="accordion" Expanding="Accordion_Expanding">
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Section 1" Margin="16,14,0,14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="Content 1" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>C#:
private void Accordion_Expanding(object sender, ExpandingAndCollapsingEventArgs e)
{
// Log the expansion attempt
Debug.WriteLine($"Item at index {e.Index} is about to expand");
}Cancelling Expansion
Prevent specific items from expanding:
private void Accordion_Expanding(object sender, ExpandingAndCollapsingEventArgs e)
{
// Prevent index 2 from expanding
if (e.Index == 2)
{
e.Cancel = true;
DisplayAlert("Restricted", "This section cannot be expanded", "OK");
}
}Use Cases
1. Permission Validation:
private void Accordion_Expanding(object sender, ExpandingAndCollapsingEventArgs e)
{
if (!UserHasPermission(e.Index))
{
e.Cancel = true;
DisplayAlert("Access Denied", "You don't have permission to view this section", "OK");
}
}2. Lazy Loading Data:
private void Accordion_Expanding(object sender, ExpandingAndCollapsingEventArgs e)
{
// Load data before expansion
var item = accordion.Items[e.Index];
if (item.Tag == null) // First time expanding
{
LoadDataForItem(e.Index);
item.Tag = "loaded";
}
}3. Single Expansion Enforcement (Custom):
private void Accordion_Expanding(object sender, ExpandingAndCollapsingEventArgs e)
{
// Collapse all other items when one expands
for (int i = 0; i < accordion.Items.Count; i++)
{
if (i != e.Index)
{
accordion.Items[i].IsExpanded = false;
}
}
}Expanded Event
The Expanded event fires after an accordion item has fully expanded. This event cannot be cancelled.
Event Signature:
public event EventHandler<ExpandedAndCollapsedEventArgs> Expanded;EventArgs Properties:
Index(int) - The zero-based index of the expanded item
Basic Usage
XAML:
<syncfusion:SfAccordion Expanded="Accordion_Expanded">
<!-- Items -->
</syncfusion:SfAccordion>C#:
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
Debug.WriteLine($"Item at index {e.Index} is now expanded");
}Use Cases
1. Analytics Tracking:
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
// Track which sections users view
Analytics.LogEvent($"Accordion_Section_{e.Index}_Expanded");
}2. Load Heavy Content After Expansion:
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
var item = accordion.Items[e.Index];
if (item.Content is Grid grid)
{
// Load images or heavy content now that item is visible
LoadImagesForSection(grid, e.Index);
}
}3. Scroll to Top:
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
// Automatically scroll expanded item to top
accordion.BringIntoView(accordion.Items[e.Index]);
}4. Update UI Elements:
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
// Update status label
statusLabel.Text = $"Viewing: {GetSectionTitle(e.Index)}";
}Collapsing Event
The Collapsing event fires before an accordion item begins to collapse. You can cancel the collapse by setting e.Cancel = true.
Event Signature:
public event EventHandler<ExpandingAndCollapsingEventArgs> Collapsing;EventArgs Properties:
Index(int) - The zero-based index of the item being collapsedCancel(bool) - Set totrueto cancel collapse
Basic Usage
XAML:
<syncfusion:SfAccordion Collapsing="Accordion_Collapsing">
<!-- Items -->
</syncfusion:SfAccordion>C#:
private void Accordion_Collapsing(object sender, ExpandingAndCollapsingEventArgs e)
{
Debug.WriteLine($"Item at index {e.Index} is about to collapse");
}Cancelling Collapse
Prevent specific items from collapsing:
private void Accordion_Collapsing(object sender, ExpandingAndCollapsingEventArgs e)
{
// Keep first item always expanded
if (e.Index == 0)
{
e.Cancel = true;
}
}Use Cases
1. Unsaved Changes Warning:
private void Accordion_Collapsing(object sender, ExpandingAndCollapsingEventArgs e)
{
if (HasUnsavedChanges(e.Index))
{
var result = DisplayAlert("Unsaved Changes",
"You have unsaved changes. Collapse anyway?",
"Yes", "No");
if (!result.Result)
{
e.Cancel = true;
}
}
}2. Form Validation:
private void Accordion_Collapsing(object sender, ExpandingAndCollapsingEventArgs e)
{
if (!ValidateFormInSection(e.Index))
{
e.Cancel = true;
DisplayAlert("Validation Error", "Please fill all required fields", "OK");
}
}3. Keep Critical Sections Open:
private void Accordion_Collapsing(object sender, ExpandingAndCollapsingEventArgs e)
{
// Prevent collapse of sections marked as critical
var item = accordion.Items[e.Index];
if (item.Tag as string == "critical")
{
e.Cancel = true;
DisplayAlert("Notice", "This section must remain visible", "OK");
}
}Collapsed Event
The Collapsed event fires after an accordion item has fully collapsed. This event cannot be cancelled.
Event Signature:
public event EventHandler<ExpandedAndCollapsedEventArgs> Collapsed;EventArgs Properties:
Index(int) - The zero-based index of the collapsed item
Basic Usage
XAML:
<syncfusion:SfAccordion Collapsed="Accordion_Collapsed">
<!-- Items -->
</syncfusion:SfAccordion>C#:
private void Accordion_Collapsed(object sender, ExpandedAndCollapsedEventArgs e)
{
Debug.WriteLine($"Item at index {e.Index} is now collapsed");
}Use Cases
1. Clean Up Resources:
private void Accordion_Collapsed(object sender, ExpandedAndCollapsedEventArgs e)
{
// Dispose of heavy resources when collapsed
var item = accordion.Items[e.Index];
if (item.Content is Grid grid)
{
UnloadImagesForSection(grid);
}
}2. Reset UI State:
private void Accordion_Collapsed(object sender, ExpandedAndCollapsedEventArgs e)
{
// Reset any UI elements associated with this section
statusLabel.Text = "No section selected";
}3. Analytics Tracking:
private void Accordion_Collapsed(object sender, ExpandedAndCollapsedEventArgs e)
{
// Track duration section was open
var duration = DateTime.Now - sectionOpenTimes[e.Index];
Analytics.LogEvent($"Section_{e.Index}_ViewDuration", duration.TotalSeconds);
}Complete Event Example
Here's a comprehensive example using all four events:
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Toolkit.Accordion;assembly=Syncfusion.Maui.Toolkit"
x:Class="AccordionApp.MainPage">
<StackLayout>
<Label x:Name="statusLabel"
Text="No events yet"
Padding="16"
BackgroundColor="LightGray" />
<syncfusion:SfAccordion x:Name="accordion"
Expanding="Accordion_Expanding"
Expanded="Accordion_Expanded"
Collapsing="Accordion_Collapsing"
Collapsed="Accordion_Collapsed">
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Public Section" Margin="16,14,0,14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="This section can expand/collapse freely" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Restricted Section" Margin="16,14,0,14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid Padding="16">
<Label Text="This section cannot be expanded" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>
</StackLayout>
</ContentPage>MainPage.xaml.cs:
using Syncfusion.Maui.Accordion;
public partial class MainPage : ContentPage
{
private Dictionary<int, DateTime> openTimes = new Dictionary<int, DateTime>();
public MainPage()
{
InitializeComponent();
}
private void Accordion_Expanding(object sender, ExpandingAndCollapsingEventArgs e)
{
statusLabel.Text = $"Expanding item {e.Index}...";
// Prevent index 1 from expanding
if (e.Index == 1)
{
e.Cancel = true;
statusLabel.Text = "Access Denied: Section 1 is restricted";
DisplayAlert("Restricted", "This section cannot be expanded", "OK");
}
}
private void Accordion_Expanded(object sender, ExpandedAndCollapsedEventArgs e)
{
statusLabel.Text = $"Item {e.Index} is now expanded";
openTimes[e.Index] = DateTime.Now;
// Track analytics
Debug.WriteLine($"Section {e.Index} opened at {DateTime.Now}");
}
private void Accordion_Collapsing(object sender, ExpandingAndCollapsingEventArgs e)
{
statusLabel.Text = $"Collapsing item {e.Index}...";
// Could add validation here if needed
}
private void Accordion_Collapsed(object sender, ExpandedAndCollapsedEventArgs e)
{
statusLabel.Text = $"Item {e.Index} is now collapsed";
// Calculate view duration
if (openTimes.ContainsKey(e.Index))
{
var duration = DateTime.Now - openTimes[e.Index];
Debug.WriteLine($"Section {e.Index} was open for {duration.TotalSeconds:F1} seconds");
openTimes.Remove(e.Index);
}
}
}Best Practices
1. Keep Event Handlers Fast
Avoid long-running operations in event handlers - use async methods or background tasks for heavy work.
2. Use Cancellable Events for Validation
Use Expanding and Collapsing events for validation before state changes.
3. Use Completion Events for Updates
Use Expanded and Collapsed events for updating UI or analytics after state changes.
4. Provide User Feedback
When cancelling an event, inform the user why with a dialog or message.
5. Avoid Recursive Calls
Don't modify IsExpanded inside event handlers for the same accordion - it can cause infinite loops.
Troubleshooting
Problem: Events firing multiple times Solution: Ensure you're not programmatically changing IsExpanded inside event handlers
Problem: Cancel doesn't work Solution: Only Expanding and Collapsing support cancellation - Expanded and Collapsed do not
Problem: Index out of range error Solution: Check accordion.Items.Count before accessing items by index
Problem: Event handler not firing Solution: Verify the event is wired up in XAML or C# and the handler signature matches
Additional Resources
Getting Started with .NET MAUI Accordion
This guide walks you through setting up and configuring the Syncfusion .NET MAUI Accordion (SfAccordion) in your application.
Installation
Step 1: Install the NuGet Package
The Accordion control is part of the Syncfusion.Maui.Toolkit package.
Option A: Using .NET CLI
dotnet add package Syncfusion.Maui.ToolkitOption B: Using Package Manager Console (Visual Studio)
Install-Package Syncfusion.Maui.ToolkitOption C: Using NuGet Package Manager UI 1. Right-click the project in Solution Explorer 2. Select Manage NuGet Packages 3. Search for Syncfusion.Maui.Toolkit 4. Click Install
Step 2: Restore Dependencies
After installation, restore the project:
dotnet restoreHandler Registration
In the MauiProgram.cs file, register the handler for Syncfusion® Toolkit.
MauiProgram.cs:
using Microsoft.Maui;
using Microsoft.Maui.Hosting;
using Microsoft.Maui.Controls.Hosting;
using Syncfusion.Maui.Toolkit.Hosting;
namespace YourAppNamespace
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
builder.ConfigureSyncfusionToolkit(); // ← Register Syncfusion handler
return builder.Build();
}
}
}⚠️ Important: Call ConfigureSyncfusionToolkit() before Build(). Failure to register the handler will result in runtime errors.
Basic Accordion Setup
Import the Namespace
Add the Syncfusion.Maui.Toolkit namespace to your XAML or C# file.
XAML:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Toolkit.Accordion;assembly=Syncfusion.Maui.Toolkit"
x:Class="YourApp.MainPage">
<!-- Content -->
</ContentPage>C#:
using Syncfusion.Maui.Toolkit;Initialize SfAccordion
XAML:
<ContentPage xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Toolkit.Accordion;assembly=Syncfusion.Maui.Toolkit">
<syncfusion:SfAccordion />
</ContentPage>C#:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
SfAccordion accordion = new SfAccordion();
this.Content = accordion;
}
}Defining Accordion Items
Each accordion item consists of a Header and Content. Both accept any .NET MAUI View.
⚠️ Important: Do not use Label directly as a child of Header or Content. Always wrap it inside a container like Grid to avoid crashes.
Example: Simple Accordion with Items
<syncfusion:SfAccordion>
<syncfusion:SfAccordion.Items>
<!-- First Item -->
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Robin Rane"
Margin="16,14,0,14"
CharacterSpacing="0.25"
FontFamily="Roboto-Regular"
FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid BackgroundColor="#f4f4f4" Padding="16">
<StackLayout>
<Label Text="Position: Chairman" FontSize="14" />
<Label Text="Organization: ABC Inc." FontSize="14" />
<Label Text="Location: Boston" FontSize="14" />
<Label Text="Phone: (617) 555-1234" FontSize="14" />
</StackLayout>
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
<!-- Second Item -->
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48">
<Label Text="Paul Vent"
Margin="16,14,0,14"
FontSize="14" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid BackgroundColor="#f4f4f4" Padding="16">
<StackLayout>
<Label Text="Position: General Manager" FontSize="14" />
<Label Text="Organization: XYZ Corp." FontSize="14" />
<Label Text="Location: New York" FontSize="14" />
<Label Text="Phone: (212) 555-1234" FontSize="14" />
</StackLayout>
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>Expand Modes
The ExpandMode property controls how many items can be expanded simultaneously.
Single Mode (Default)
Only one item can be expanded at a time. Expanding a new item collapses the previously expanded item.
<syncfusion:SfAccordion ExpandMode="Single">
<!-- Items -->
</syncfusion:SfAccordion>accordion.ExpandMode = AccordionExpandMode.Single;Multiple Mode
Multiple items can be expanded simultaneously. Expanding a new item does not collapse others.
<syncfusion:SfAccordion ExpandMode="Multiple">
<!-- Items -->
</syncfusion:SfAccordion>accordion.ExpandMode = AccordionExpandMode.Multiple;MultipleOrNone Mode
Multiple items can be expanded, and tapping an expanded item's header collapses it without expanding another.
<syncfusion:SfAccordion ExpandMode="MultipleOrNone">
<!-- Items -->
</syncfusion:SfAccordion>accordion.ExpandMode = AccordionExpandMode.MultipleOrNone;Animation Customization
Animation Duration
Customize the expand/collapse animation duration (in milliseconds). Default is 200ms.
<syncfusion:SfAccordion AnimationDuration="300">
<!-- Items -->
</syncfusion:SfAccordion>accordion.AnimationDuration = 300;Animation Easing
Control the animation easing style. Default is Linear.
Available Easing Options:
- Linear
- SinOut
- SinIn
- SinInOut
- CubicIn
- CubicOut
- CubicInOut
<syncfusion:SfAccordion AnimationDuration="250"
AnimationEasing="SinOut">
<!-- Items -->
</syncfusion:SfAccordion>accordion.AnimationDuration = 250;
accordion.AnimationEasing = ExpanderAnimationEasing.SinOut;Item Spacing
Add vertical spacing between accordion items using the ItemSpacing property.
<syncfusion:SfAccordion ItemSpacing="8">
<!-- Items -->
</syncfusion:SfAccordion>accordion.ItemSpacing = 8.0;Auto Scroll Position
Control where the expanded item scrolls to after expansion using AutoScrollPosition. Default is MakeVisible.
Options:
- MakeVisible: Scrolls just enough to make the item visible
- Top: Scrolls the expanded item to the top of the view
<syncfusion:SfAccordion AutoScrollPosition="Top">
<!-- Items -->
</syncfusion:SfAccordion>accordion.AutoScrollPosition = AccordionAutoScrollPosition.Top;Programmatic Scrolling with BringIntoView
Use the BringIntoView method to programmatically scroll a specific item into view.
// Bring the item at index 5 into view
accordion.BringIntoView(accordion.Items[5]);Example with Button:
<StackLayout>
<Button Text="Scroll to Item 5" Clicked="ScrollButton_Clicked" />
<syncfusion:SfAccordion x:Name="accordion">
<!-- 10+ items -->
</syncfusion:SfAccordion>
</StackLayout>private void ScrollButton_Clicked(object sender, EventArgs e)
{
if (accordion.Items.Count > 5)
{
accordion.BringIntoView(accordion.Items[5]);
}
}Running the Application
Press F5 or run:
dotnet build
dotnet runThe accordion will display with your configured items and settings.
Complete Example
Here's a complete working example:
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Toolkit.Accordion;assembly=Syncfusion.Maui.Toolkit"
x:Class="AccordionApp.MainPage">
<syncfusion:SfAccordion ExpandMode="Single"
AnimationDuration="250"
AnimationEasing="SinOut"
ItemSpacing="6"
AutoScrollPosition="MakeVisible">
<syncfusion:SfAccordion.Items>
<syncfusion:AccordionItem>
<syncfusion:AccordionItem.Header>
<Grid HeightRequest="48" BackgroundColor="White">
<Label Text="Getting Started"
Margin="16,14,0,14"
FontSize="14"
VerticalTextAlignment="Center" />
</Grid>
</syncfusion:AccordionItem.Header>
<syncfusion:AccordionItem.Content>
<Grid BackgroundColor="#f4f4f4" Padding="16">
<Label Text="Learn the basics of .NET MAUI Accordion, including installation and setup."
LineBreakMode="WordWrap" />
</Grid>
</syncfusion:AccordionItem.Content>
</syncfusion:AccordionItem>
</syncfusion:SfAccordion.Items>
</syncfusion:SfAccordion>
</ContentPage>Next Steps
- Data Binding: See data-binding.md to bind accordion items to ObservableCollection
- Appearance: See appearance-customization.md to customize colors, icons, and Visual States
- Events: See events.md to handle expansion/collapse events
- Advanced: See advanced-features.md for Liquid Glass Effect and more
Troubleshooting
Problem: "Handler not registered" error Solution: Ensure ConfigureSyncfusionToolkit() is called in MauiProgram.cs
Problem: Label crashes when used as Header/Content Solution: Wrap Label inside a Grid or other container
Problem: NuGet restore fails Solution: Run dotnet restore manually and check your internet connection
Problem: Accordion doesn't display Solution: Verify the Syncfusion.Maui.Toolkit package is installed and the namespace is imported correctly
Related skills
How it compares
Component-focused MAUI procedural skill, not a general mobile design system or backend API skill.
FAQ
Who is syncfusion-maui-toolkit-accordion for?
and small-team.NET MAUI developers using Syncfusion controls who want correct accordion expand-and-scroll behavior from their coding agent.
When should I use syncfusion-maui-toolkit-accordion?
During Build frontend when you implement or refine SfAccordion in settings, FAQs, or multi-step forms and need MakeVisible vs Top scroll policies.
Is syncfusion-maui-toolkit-accordion safe to install?
It is documentation-only UI guidance with no shell or network hooks—still review the Security Audits panel on this page before adding any skill to your agent environment.