Back to Devexpress

How to: Bind the AccordionControl to Data Using the ChildrenSelector Property

wpf-119898-controls-and-libraries-navigation-controls-accordion-control-examples-how-to-bind-the-accordioncontrol-to-data-using-the-childrenselector-property.md

latest7.4 KB
Original Source

How to: Bind the AccordionControl to Data Using the ChildrenSelector Property

  • Jun 07, 2019
  • 3 minutes to read

This example demonstrates how to bind the AccordionControl to data using the AccordionControl.ChildrenSelector property.

The AccordionControl is bound to a data source. A panel on the right contains the dedicated Expand and Collapse buttons and allows editing a description of the currently selected item. A children selector and implicit data templates are used to build the accordion item hierarchy.

The image below shows the result:

Refer to the Data Binding topic to learn more.

View Example

csharp
using DevExpress.Xpf.Accordion;
using System.Collections;
using System.Collections.Generic;

namespace ChildrenSelector {

    public class ViewModel {
        public Data MyData { get; set; }
        public object SelectedItem { get; set; }
        public ViewModel() {
            MyData = new Data();
        }
    }
    public class Data {
        public List<Category> Categories { get; set; }
        public Data() {
            Categories = new List<Category>();
            List<Item> subitems = new List<Item>();
            subitems.Add(new Item() { ItemName = "Chair", Description = "A red chair." });
            subitems.Add(new Item() { ItemName = "Table", Description = "An old table." });
            Categories.Add(new Category() { CategoryName = "Furniture", Items = subitems });
            List<Item> books = new List<Item>();
            books.Add(new Item() { ItemName = "Dictionary", Description = "My old French-English Dictionary" });
            Categories.Add(new Category() { CategoryName = "Books", Items = books });
        }
    }
    public class Category {
        public string CategoryName { get; set; }
        public string Description { get; set; }
        public List<Item> Items { get; set; }
    }
    public class Item {
        public string ItemName { get; set; }
        public string Description { get; set; }
    }

    public class MySelector : IChildrenSelector {
        public IEnumerable SelectChildren(object item) {
            if (item is Category) {
                return ((Category)item).Items;
            } else return null;
        }
    }
}
xaml
<dx:DXWindow
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
        xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
        xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
        xmlns:dxa="http://schemas.devexpress.com/winfx/2008/xaml/accordion" 
        xmlns:local="clr-namespace:ChildrenSelector" 
        x:Class="ChildrenSelector.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <dx:DXWindow.Resources>
        <local:MySelector x:Key="mySelector"/>
    </dx:DXWindow.Resources>
    <dx:DXWindow.DataContext>
        <local:ViewModel/>
    </dx:DXWindow.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <Border Margin="5" Grid.Column="0" BorderBrush="Black" BorderThickness="1">
            <dxa:AccordionControl Name="accordion" SelectionUnit="SubItem" ItemsSource="{Binding MyData.Categories }" 
                                  SelectedItem="{Binding SelectedItem}" ChildrenSelector="{StaticResource mySelector}">
                <dxa:AccordionControl.Resources>
                    <DataTemplate DataType="{x:Type local:Category}">
                        <TextBlock Text="{Binding CategoryName}"/>
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type local:Item}">
                        <TextBlock Text="{Binding ItemName}"/>
                    </DataTemplate>
                </dxa:AccordionControl.Resources>
            </dxa:AccordionControl>
        </Border>
        <Border Margin="5" Grid.Column="1" BorderBrush="Black" BorderThickness="1">
            <StackPanel>
                <StackPanel Orientation="Horizontal">
                    <Label Margin="5" VerticalAlignment="Center">Item Name</Label>
                    <dxe:TextEdit Margin="5" Width="150" Text="{Binding SelectedItem.Description}"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <Button Margin="5" Content="Expand All Items" 
                            Command="{Binding ElementName=accordion, Path=Commands.ExpandAllItems}" />
                    <Button Margin="5" Content="Collapse All Items" 
                            Command="{Binding ElementName=accordion, Path=Commands.CollapseAllItems}" />
                </StackPanel>
            </StackPanel>
        </Border>
    </Grid>
</dx:DXWindow>
vb
Imports DevExpress.Xpf.Accordion
Imports System.Collections
Imports System.Collections.Generic

Namespace ChildrenSelector

    Public Class ViewModel
        Public Property MyData() As Data
        Public Property SelectedItem() As Object
        Public Sub New()
            MyData = New Data()
        End Sub
    End Class
    Public Class Data
        Public Property Categories() As List(Of Category)
        Public Sub New()
            Categories = New List(Of Category)()
            Dim subitems As New List(Of Item)()
            subitems.Add(New Item() With { _
                .ItemName = "Chair", _
                .Description = "A red chair." _
            })
            subitems.Add(New Item() With { _
                .ItemName = "Table", _
                .Description = "An old table." _
            })
            Categories.Add(New Category() With { _
                .CategoryName = "Furniture", _
                .Items = subitems _
            })
            Dim books As New List(Of Item)()
            books.Add(New Item() With { _
                .ItemName = "Dictionary", _
                .Description = "My old French-English Dictionary" _
            })
            Categories.Add(New Category() With { _
                .CategoryName = "Books", _
                .Items = books _
            })
        End Sub
    End Class
    Public Class Category
        Public Property CategoryName() As String
        Public Property Description() As String
        Public Property Items() As List(Of Item)
    End Class
    Public Class Item
        Public Property ItemName() As String
        Public Property Description() As String
    End Class

    Public Class MySelector
        Implements IChildrenSelector

        Public Function SelectChildren(item As Object) As IEnumerable Implements IChildrenSelector.SelectChildren
            If TypeOf item Is Category Then
                Return DirectCast(item, Category).Items
            Else
                Return Nothing
            End If
        End Function
    End Class
End Namespace