How to sort TreeView items using SortDescriptions in Xaml?

后端 未结 3 675
粉色の甜心
粉色の甜心 2020-11-30 11:38

I have a list of Layers binded to a TreeView where each instance has a list of Effects. I show them via a HierarchicalDataTemplate whi

相关标签:
3条回答
  • 2020-11-30 12:15

    I find using a multi converter is better:

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Globalization;
    using System.Windows.Data;
    
    namespace Converters
    {
        [ValueConversion(typeof(object[]), typeof(ListCollectionView))]
        public class IListToListCollectionViewConverter : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
                var Length = values.Length;
                if (Length >= 1 && Length < 3)
                {
                    var IList = values[0] as IList;
    
                    var SortName = string.Empty;
                    if (Length > 1)
                        SortName = values[1].ToString();
    
                    var SortDirection = ListSortDirection.Ascending;
                    if (Length > 2)
                        SortDirection = values[2] is ListSortDirection ? (ListSortDirection)values[2] : (values[2] is string ? (ListSortDirection)Enum.Parse(typeof(ListSortDirection), values[2].ToString()) : SortDirection);
    
                    var Result = new ListCollectionView(IList);
                    Result.SortDescriptions.Add(new SortDescription(SortName, SortDirection));
                    return Result;
                }
                return null;
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 12:23

    This is not the XAML based solution, but I was facing the same problem and found the solution like below,

    I am assuming you have 3 classes like below: AllLayers, Layers & Effects

    class AllLayers
    {
        public AllLayers()
        {
            layers = new ObservableCollection<Layers>();
            var collectionView = CollectionViewSource.GetDefaultView(layers);
            collectionView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
            collectionView.SortDescriptions.Add(new SortDescription("Color", ListSortDirection.Ascending));
        }
        public ObservableCollection<Layers> layers { get; }
    }
    class Layers
    {
        public Layers(string name, string color)
        {
            Name = name;
            Color = color;
            CollectionViewSource.GetDefaultView(effects).SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
        }
        public string Name { get; set; }
        public string Color { get; set; }
        public ObservableCollection<Effects> effects { get; }
    }
    class Effects
    {
        public string Name { get; set; }
    }
    

    After that, your existing binding should work with sorting. No need of change to your XAML or anything.

    0 讨论(0)
  • 2020-11-30 12:24

    I would suggest to use converter to sort sub items. Something like this:

    <TreeView Name="treeCategories" Margin="5" ItemsSource="{Binding Source={StaticResource SortedLayers}}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Effects, Converter={StaticResource myConverter}, ConverterParameter=EffectName}">
            <TextBlock Text="{Binding Path=LayerName}" />
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=EffectName}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
    

    and converter:

    
    public class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            System.Collections.IList collection = value as System.Collections.IList;
            ListCollectionView view = new ListCollectionView(collection);
            SortDescription sort = new SortDescription(parameter.ToString(), ListSortDirection.Ascending);
            view.SortDescriptions.Add(sort);
    
            return view;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
    
    0 讨论(0)
提交回复
热议问题