Custom Expand/Collapse indicator

2 posts, 0 answers
  1. VPS
    VPS avatar
    30 posts
    Member since:
    Jan 2015

    Posted 26 Jun 2018 Link to this post

    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.

     

     

     

     

  2. Shawn
    Shawn avatar
    2 posts
    Member since:
    Nov 2017

    Posted 26 Jun 2018 in reply to VPS Link to this post

    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; }
        }

     

     

Back to Top