This is a migrated thread and some comments may be shown as answers.

Custom Expand/Collapse indicator

1 Answer 187 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Cleanwatts
Top achievements
Rank 1
Cleanwatts asked on 26 Jun 2018, 11:15 AM

I'm trying to create a custom expand / collapse indicator for my tree items but there is one situation where it is not working: when the item has no children the indicator is wrong. I'm using the technique suggested in this forum post to fill my tree on demand.

I have tried two different approaches but neither one gives an accurate result.

1. Binding to IsExpanded:

I have created a value converter:

public class TreeIconConverter : IValueConverter
{
    public string ExpandIcon { get; set; }
    public string CollapseIcon { get; set; }
    public string LeafIcon { get; set; }
 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool expanded)
            return expanded ? CollapseIcon : ExpandIcon;
        return null;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

and I'm using a Label as the custom tree indicator:

<Label HeightRequest="24" WidthRequest="24" HorizontalOptions="Center" VerticalOptions="Center"
    FontFamily="{StaticResource IconFont}" FontSize="{StaticResource SelectionIconSize}"
    Text="{Binding IsExpanded, Converter={StaticResource TreeIconConverter}}"/>

 

This gives the best result, but when the item has no children the ExpandIcon is shown. 

2. Binding to TreeViewDataItem:

I have altered the value converter to try and detect when the item has children:

public class TreeIconConverter : IValueConverter
{
    public string ExpandIcon { get; set; }
    public string CollapseIcon { get; set; }
    public string LeafIcon { get; set; }
 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is TreeViewDataItem item)
        {
            if (!item.IsExpanded)
                return CollapseIcon;
 
            if (item.Item is LocationGroup group)
            {
                if (group.HaveChildren && group.Children.Count == 0)
                    return LeafIcon;
            }
 
            return ExpandIcon;
        }
 
        return null;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

group.HaveChildren is true only after getting the group's children, if it's false we don't yet have the group's children in memory.

The Label has been changed to:

<Label HeightRequest="24" WidthRequest="24" HorizontalOptions="Center" VerticalOptions="Center"
    FontFamily="{StaticResource IconFont}" FontSize="{StaticResource SelectionIconSize}"
    Text="{Binding ., Converter={StaticResource TreeIconConverter}}"/>

With this second version, all the items always show the CollapseIcon.

 

 

 

 

1 Answer, 1 is accepted

Sort by
0
Shawn
Top achievements
Rank 1
answered on 26 Jun 2018, 09:24 PM

I have just started working with this control and was able to achieve some success using DataTemplate.

<telerikDataControls:RadTreeView x:Name="treeView" ItemsSource="{Binding Source}"
                                         DisplayMemberPath="Name"                                       
                                         ItemExpanded="treeView_ItemExpanded"
                                         ItemCollapsed="treeView_ItemCollapsed">
            <telerikDataControls:RadTreeView.ItemTemplate>
                <DataTemplate >
                    <StackLayout Orientation="Horizontal" Margin="{Binding Path=Item.Margin}" >
                        <Label Grid.Column="0" Text="➤" FontSize="20" TextColor="Black" VerticalOptions="Center" >
                            <Label.Triggers>
                                <DataTrigger TargetType="Label" Binding="{Binding Path=Item.IsExpanded}" Value="True">
                                    <Setter Property="Rotation" Value="90"/>
                                </DataTrigger>
                            </Label.Triggers>
                        </Label>
                        <Label Text="{Binding Path=Item.Name}" VerticalOptions="Center"/>
                        <Entry Focused="Entry_Focused" />
                    </StackLayout>
                </DataTemplate>
            </telerikDataControls:RadTreeView.ItemTemplate>

</telerikDataControls:RadTreeView>

 

public class TestItem : INotifyPropertyChanged
    {
 
        #region PropertyChanged
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        public void RaisePropertyChanged(string property)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
        }
 
        #endregion
 
        public TestItem(string name, int leftMargin)
        {
            Name = name;
 
            Margin = new Thickness(leftMargin, 0, 0, 0);
        }
 
        public string Name { get; set; }
 
        private bool _IsExpanded;
 
        public bool IsExpanded
        {
            get { return _IsExpanded; }
            set { _IsExpanded = value; RaisePropertyChanged(nameof(IsExpanded)); }
        }
 
        private Thickness _Margin = new Thickness(25,0,0,0);
 
        public Thickness Margin
        {
            get { return _Margin; }
            set { _Margin = value; RaisePropertyChanged(nameof(Margin)); }
        }
 
 
        public List<TestItem> Children { get; set; }
    }

 

 

Tags
TreeView
Asked by
Cleanwatts
Top achievements
Rank 1
Answers by
Shawn
Top achievements
Rank 1
Share this question
or