New to Telerik UI for Xamarin? Download free 30-day trial

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