Expand Collapse TreeView item when tapping on the indicator

Environment

Product Version
Product TreeView for Xamarin

Description

The purpose of this help article is to show you how to expand/collapse treeview item when tapping only on the arrow (expand/collapse indicator)

Solution

The solution is to suppress the default TreeView ItemTap Command, then add a TapGestureRecognized to the Expand Collapse Indicator and triher the expand/collapse state.

Her eis the implementation:

RadTreeView definition

<ContentPage.Resources>
        <treeView:LevelToMarginConverter x:Key="levelToMarginConverter" />
    </ContentPage.Resources>
    <Grid>
        <telerikDataControls:RadTreeView  x:Name="treeView"
                                  ItemsSource="{Binding Source}"                                  
                                  ItemCollapsed="TreeView_OnItemCollapsed" 
                                  ItemExpanded="TreeView_OnItemExpanded"
                                  NativeControlLoaded="TreeView_OnNativeControlLoaded">
            <telerikDataControls:RadTreeView.Commands>
                <commands:TreeViewUserCommand Id="ItemTap" SuppressDefaultCommand="True"/>
            </telerikDataControls:RadTreeView.Commands>
            <telerikDataControls:TreeViewDescriptor DisplayMemberPath="Name"
                                            ItemsSourcePath="Cities"
                                            TargetType="{x:Type local:Country}">
                <telerikDataControls:TreeViewDescriptor.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="{Binding Path=Level, Converter={StaticResource levelToMarginConverter}}"
                                  HeightRequest="40">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="10"/>
                                <ColumnDefinition  />
                            </Grid.ColumnDefinitions>
                            <treeView:ExpandCollapseIndicator FontSize="Medium"
                                                                  WidthRequest="10"
                                                                  VerticalTextAlignment="Center"
                                                                  IsLoading="{Binding Path=IsLoading}"
                                                                  IsLoadOnDemandEnabled="{Binding Path=IsLoadOnDemandEnabled}"
                                                                  IsExpanded="{Binding Path=IsExpanded}"
                                                                  IsLeaf="{Binding Path=IsLeaf}">
                                <treeView:ExpandCollapseIndicator.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1"/>
                                </treeView:ExpandCollapseIndicator.GestureRecognizers>
                            </treeView:ExpandCollapseIndicator>

                            <treeView:ItemText Grid.Column="1"
                                                   VerticalOptions="Center"
                                                   Text="{Binding Item.Name}" />
                        </Grid>
                    </DataTemplate>
                </telerikDataControls:TreeViewDescriptor.ItemTemplate>
            </telerikDataControls:TreeViewDescriptor>
            <telerikDataControls:TreeViewDescriptor DisplayMemberPath="Name" 
                                            TargetType="{x:Type local:City}">
                <telerikDataControls:TreeViewDescriptor.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="{Binding Path=Level, Converter={StaticResource levelToMarginConverter}}" HeightRequest="40">
                            <treeView:ItemText Margin="8,0,0,0"
                                                   VerticalOptions="Center"
                                                   Text="{Binding Item.Name}" />
                        </Grid>
                    </DataTemplate>
                </telerikDataControls:TreeViewDescriptor.ItemTemplate>
            </telerikDataControls:TreeViewDescriptor>
        </telerikDataControls:RadTreeView>
    </Grid>

</ContentPage>

You will need to add the following namespaces

xmlns:telerikDataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls" 
xmlns:treeView="clr-namespace:Telerik.XamarinForms.DataControls.TreeView;assembly=Telerik.XamarinForms.DataControls" 
xmlns:commands="clr-namespace:Telerik.XamarinForms.DataControls.TreeView.Commands;assembly=Telerik.XamarinForms.DataControls"            

from the above TreeView definition, please notice how the ItemTap Commans is suppressed:

<telerikDataControls:RadTreeView.Commands>
    <commands:TreeViewUserCommand Id="ItemTap" SuppressDefaultCommand="True"/>
</telerikDataControls:RadTreeView.Commands>

TapGestureRecognizer event:

private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
    var btn = (ExpandCollapseIndicator)sender;
    var treeViewDataItem = (TreeViewDataItem)btn.BindingContext;
    if (treeViewDataItem.IsExpanded)
    {
        treeView.Collapse(treeViewDataItem.Item);
    }
    else
    {
        treeView.Expand(treeViewDataItem.Item);
    }
}

The used ViewModel

public class ViewModel
{
    public ObservableCollection<Country> Source { get; set; }

    public ViewModel()
    {
        this.Source = new ObservableCollection<Country>
        {
            new Country
            {
                Name = "Italy",
                Cities = new ObservableCollection<City> 
                {
                    new City {Name = "Rome"},
                    new City {Name = "Milano"}
                }
            },
            new Country
            {
                Name = "Germany",
                Cities = new ObservableCollection<City> {new City {Name = "Berlin"}, new City {Name = "Frankfurt"}}
            },
            new Country
            {
                Name = "India", 
                Cities = new ObservableCollection<City> {new City {Name = "Mumbai"}}
            },
            new Country
            {
                Name = "Argentina",
                Cities = new ObservableCollection<City> {new City {Name = "Buenos Aires"}}
            },
            new Country
            {
                Name = "USA",
                Cities = new ObservableCollection<City>
                {
                    new City {Name = "Miami"},
                    new City {Name = "New York"},
                    new City {Name = "Los Angeles"}
                }
            }
        };
    }
}

The Business Model Used:

public class Country : HighlightableTreeViewItemBase
{
    public string Name { get; set; }
    public ObservableCollection<City> Cities { get; set; }
}

public class City : HighlightableTreeViewItemBase
{
    public string Name { get; set; }
}

In this article