Share via


Nesting, ListView inside ListView DataTemplate (Or TreeView representation)

This article builds a data model to represent the nesting relationship which can be displayed in a tree like structure inside nested ListViews. This tries to solve this MSDN problem and create a structure as shown below

Data Model

class Menu
    {
        public ObservableCollection<TopMenu> TopMenuItems { get; set; }
        public Menu()
        {
            TopMenuItems = new ObservableCollection<TopMenu>();
        }
    }
 
    class TopMenu
    {
        public string GroupName { get; set; }
        public ObservableCollection<SubMenu> SubMenuItems { get; set; }
        public TopMenu()
        {
            SubMenuItems = new ObservableCollection<SubMenu>();
        }
    }
 
    class SubMenu
    {
        public string ItemName { get; set; } 
    }

Data in Page Constructor

            Menu menu = new Menu();

            menu.TopMenuItems.Add(new TopMenu() { GroupName = "Basic Reports - Mobile" });
            menu.TopMenuItems[0].SubMenuItems.Add(new SubMenu() { ItemName = "Sales Reports - mobile" });
            menu.TopMenuItems.Add(new TopMenu() { GroupName = "Enhanced Reports - Mobile" });
            menu.TopMenuItems[1].SubMenuItems.Add(new SubMenu() { ItemName = "Subcategory Month - mobile" });
            menu.TopMenuItems[1].SubMenuItems.Add(new SubMenu() { ItemName = "Top Categories - mobile" });
            this.DataContext = menu;

XAML for ListView 

<StackPanel Orientation="Vertical">
            <ListView Name="groupListView" ItemsSource="{Binding TopMenuItems}" CanDragItems="True" CanReorderItems="True" AllowDrop="True" IsSwipeEnabled="True" SelectionMode="None">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <Border x:Name="bordermenu">
                                <TextBlock Foreground="Red" Text="{Binding GroupName}"/>
                            </Border>
                            <ListView Name="itemListViewss" ItemsSource="{Binding SubMenuItems}" CanDragItems="True" CanReorderItems="True" AllowDrop="True" IsSwipeEnabled="True" SelectionMode="None">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Tapped="StackPanel_Tapped">
                                            <Border x:Name="bordersubmenu">
                                                <TextBlock Foreground="Blue" Text="{Binding ItemName}" x:Name="submenu" /> 
                                            </Border>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
             
            <TextBlock Name="txtSubMenuTapped" FontSize="30" Tag="Sub Menu Selected - " Text="Sub menu tapped - None"/>
        </StackPanel>

Finally, event Handler (StackPanel_Tapped defined in ListView DataTemplate) in page which takes of care of retrieving which sub-menu item was clicked or tapped.

private void StackPanel_Tapped(object sender, TappedRoutedEventArgs e)
       {
           TextBlock txtBlock = ((Windows.UI.Xaml.RoutedEventArgs)(e)).OriginalSource as TextBlock;
           if (txtBlock != null)
           {
               txtSubMenuTapped.Text = txtSubMenuTapped.Tag.ToString() + txtBlock.Text;
           }
           e.Handled = true;
       }