【问题标题】:How to sort TreeView items using SortDescriptions in Xaml?如何在 Xaml 中使用 SortDescriptions 对 TreeView 项目进行排序?
【发布时间】:2011-08-09 00:47:46
【问题描述】:

我有一个绑定到TreeViewLayers 列表,其中每个实例都有一个Effects 列表。我通过 HierarchicalDataTemplate 展示它们,效果很好,但我正在尝试使用 SortDescriptions 对它们进行排序。

我不知道如何在 xaml 中执行此操作,但这样做只会对第一级项目进行排序,而不是子项目:

ICollectionView view = CollectionViewSource.GetDefaultView ( treeView1.ItemsSource );
view.SortDescriptions.Add ( new SortDescription ( "Name", ListSortDirection.Ascending ) );

我尝试先按.Color 对它们进行排序,然后按.Name

有什么想法吗?

编辑:我添加了这段代码:

<Window.Resources>

    <CollectionViewSource x:Key="SortedLayers" Source="{Binding AllLayers}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Color" />
            <scm:SortDescription PropertyName="Name" />
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>

</Window.Resources>

但这仍然只适用于第一级层次结构。如何为每个 layer.Effects 集合指定它?

【问题讨论】:

    标签: c# .net wpf xaml sorting


    【解决方案1】:

    我建议使用转换器对子项目进行排序。 像这样的:

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

    和转换器:

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

    【讨论】:

    • 只是一个很小的改进,将 System.Collections.IList 的值更改为 (System.Collections.IList)value 以避免在 value 不是 IList 时出现空引用异常(你应该有一个InvalidCastException)
    【解决方案2】:

    我发现使用多转换器更好:

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

    【讨论】:

    • 如何更好?你能展示一下 xaml 来使用它吗?
    【解决方案3】:

    这不是基于 XAML 的解决方案,但我遇到了同样的问题并找到了如下解决方案,

    我假设你有如下 3 个类: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; }
    }
    

    之后,您现有的绑定应该可以与排序一起使用。无需更改您的 XAML 或任何东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-26
      • 2013-06-08
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      相关资源
      最近更新 更多