Click here to Skip to main content
15,886,199 members
Articles / Desktop Programming / XAML
Tip/Trick

Acordian Listview in XAML Windows Application

Rate me:
Please Sign up or sign in to vote.
3.34/5 (6 votes)
7 Oct 2015CPOL3 min read 16.3K   6   7
How to create an Acordian view for ListView in XAML for Windows WPF, Store, Mobile Application

Introduction

This tip is for the Windows Mobile, Store, UWP, WPF Application developer who wants to create an acordian kind of control in to his/her application. There is no in built control in  XAML which supports the acordian view. So to achieve this functionality, the developers have created their own control in XAML.

This is how the Acordian View looks like:

 

Background

To create an Acordian Control, you must be familiar with the Listview in the XAML. You must know how to create an Inner ListView in XAML. It depends upon the user requirement for which control (like Listview, gridView) it wants to create an Accodian view. Most of the people in Windows also call it as a treeview.

Using the Code

  1. There is no inbuilt class available in XAML which supports the Acordian view.
  2. In the above figure, you can see the one header with the Listview and inner one again contains listview so it means that you need to create listview inside another listview in XAML.
XML
<ListView x:Name="MainListView" Grid.Row="1" ItemsSource="{Binding TimeTrack}" SelectionMode="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="10*"/>
                            <RowDefinition Height="80*"/>
                        </Grid.RowDefinitions>
                        <Grid Margin="40 0 0 0" Background="#757373" Width="1860" 
				Grid.Row="0" Height="65">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="5*"/>
                                <ColumnDefinition Width="15*"/>
                            </Grid.ColumnDefinitions>
                            <!--<-->

                  <Textblock text x:key="textBlockName" Text="{Binding Name}">
        
                        <ListView x:Name="ListViewInner" 
				ItemsSource="{Binding UnApprovedTimeEntities}" 
				Grid.Row="1" Margin="40 0 0 0" Visibility="Collapsed"
                                SelectionMode="None" Background="Transparent"
                              HeaderTemplate="{StaticResource HeaderDataTemplateGLApproveInnerListView}"
				 ItemTemplate="{StaticResource ItemTemplateGLApproveInnerListView }">
                        </ListView>
                        <!--End of Inner List View-->
                        <!--</Grid>-->
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

The key things in the above code are as follows:

  1. There are two Listviews. Parent ListView Name is MainListView and the other one is Innerlistview.
  2. There is a plus button present at the Parent listview. Once the user taps on the Parent listview button, then Inner listview will be loaded.
  3. The critical thing here is as we have taken the Innerlist inside the parentList, so it means if you are setting the itemsource to parentlist, then the itemsource of innerlist will also gets binded.
  4. There are two ways of showing the inner listview - one is via the ViewModel itself and the other is via code behind.
  5. I will suggest you to go for code behind. I also tried to achieve the above functionality via viewModel but it was not working.
  6. Create a Tapped Event for the button of parentlist which will open the inner listview.
    1. Now on the tap of the button, we have made the Visibility of innerlistview either Visible or Collapsed
    2. By default, set the Visibility of the inner Listview as Collapsed.
    3. Now the trick is how will you find the name of Innerlistview because Innerlistview is the part of data template of listview. Keep this thing in mind that you can Never Access Any item inside the Data template of any  ItemControl (ListView, GridView, ListBox) Datatemplate. To achieve it first, you have to find the name of innerlistview.

If you will do the above handling via Viewmodel that is Collapsing and showing visibility to Listview, then you can do it, but once you will tap on the button, then it will open the innerlistview for all the parent listviews which will not be an acordian view. I have tried it but it has not worked.

The code is as follows:

C#
private void ButtonExpand_Tapped(object sender, TappedRoutedEventArgs e)
        {
            var button = (Button)sender;
            Grid parent = (Grid)button.Parent;
            ListView listview = (ListView)parent.FindName("ListViewInner");
            Image image = (Image)parent.FindName("ButtonExpandImage");
            if (listview.Visibility == Visibility.Visible)
            {
                listview.Visibility = Visibility.Collapsed;
                image.Source = new BitmapImage(new Uri("ms-appx:///Assets/plus.png",
                                UriKind.RelativeOrAbsolute));
            }
            else
            {
                listview.Visibility = Visibility.Visible;
                image.Source = new BitmapImage(new Uri("ms-appx:///Assets/minus.png",
                                UriKind.RelativeOrAbsolute));
            }
        }

As Grid is the Parent of the ListView, it means if you have the Parent access, then you can easily find its child by using one line of code:

C#
ListView listview = (ListView)parent.FindName("ListViewInner");

As parent is grid for both the listview in the above code, then once you will get the parent, you can find any of the children by calling the Findname method inside it. You have to pass the name of the control that you want to search.

Once you will get the access to the innerlistview, you can make it collapse or visible.

Points of Interest

How to find the name of any Control which is the part of Datatemplate of any Item Control. The below code is for opening. This code will be written inside the Event Handler of the button.

C#
var button = (Button)sender;
Grid parent = (Grid)button.Parent;
ListView listview = (ListView)parent.FindName("ListViewInner");
Image image = (Image)parent.FindName("ButtonExpandImage");

Keep one thing in mind - the parents of both the listview should be the same, otherwise the above code will not work.

History

  • 7th October, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Collabera Solution
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
SuggestionAccordion control Pin
Rupak Kr D15-Jan-20 6:01
Rupak Kr D15-Jan-20 6:01 
Questioncan you please share this code? Pin
Santhosh Kumar Chindam12-Oct-15 1:23
Santhosh Kumar Chindam12-Oct-15 1:23 
AnswerRe: can you please share this code? Pin
prince sanghi12-Oct-15 1:46
professionalprince sanghi12-Oct-15 1:46 
QuestionIssue Pin
Thornik9-Oct-15 2:59
Thornik9-Oct-15 2:59 
Questionimage is missing Pin
Tridip Bhattacharjee7-Oct-15 21:53
professionalTridip Bhattacharjee7-Oct-15 21:53 
AnswerRe: image is missing Pin
prince sanghi8-Oct-15 19:54
professionalprince sanghi8-Oct-15 19:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.