Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 展开Wpf Treeview以支持排序_C#_Wpf_C# 4.0_Treeview - Fatal编程技术网

C# 展开Wpf Treeview以支持排序

C# 展开Wpf Treeview以支持排序,c#,wpf,c#-4.0,treeview,C#,Wpf,C# 4.0,Treeview,您好,我创建了这个小示例,我想扩展它以支持排序 public class Country { public string Name { get; set; } public int SortOrder { get; set; } } 我的xaml: <TreeView Name="CountryTreeView" ItemsSource="{Binding}"> <TreeView.ItemTemplate> <DataTemplate

您好,我创建了这个小示例,我想扩展它以支持排序

public class Country
{
    public string Name { get; set; }
    public int SortOrder { get; set; }
}
我的xaml:

<TreeView Name="CountryTreeView" ItemsSource="{Binding}">
  <TreeView.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Path=Name}"/>
    </DataTemplate>
  </TreeView.ItemTemplate>
</TreeView>

以及背后的代码:

readonly ObservableCollection<Country> Countries;

public MainWindow()
{
   InitializeComponent();

   Countries = new ObservableCollection<Country>
   {
       new Country{Name = "Denmark", SortOrder = 0},
       new Country{Name = "Norway", SortOrder = 1},
       new Country{Name = "Sweden", SortOrder = 2},
       new Country{Name = "Iceland", SortOrder = 3},
       new Country{Name = "Greenland", SortOrder = 4},
   };

   CountryTreeView.DataContext = Countries;
}
只读可观察收集国家/地区;
公共主窗口()
{
初始化组件();
国家/地区=新的可观测集合
{
新国家{Name=“丹麦”,SortOrder=0},
新国家{Name=“挪威”,SortOrder=1},
新国家{Name=“瑞典”,SortOrder=2},
新国家{Name=“冰岛”,SortOrder=3},
新国家{Name=“格陵兰”,SortOrder=4},
};
CountryTreeView.DataContext=国家/地区;
}
我想让
Treeview
能够根据
SortOrder
值对
国家进行排序

它需要能够在飞行中做到这一点。
因此,例如,如果我将Name=“丹麦”的排序规则更改为
SortOrder
=10,则
树视图将自动反映这一点。

我认为树视图没有默认排序。您可以在将项目输入集合之前对其进行排序,也可以覆盖ObservableCollection以包含排序方法

我在我的一个项目中覆盖它:

public class SortableObservableCollection<T> : ObservableCollection<T>
{
    // Constructors
    public SortableObservableCollection() : base(){}
    public SortableObservableCollection(List<T> l) : base(l){}
    public SortableObservableCollection(IEnumerable<T> l) :base (l) {}

    #region Sorting

    /// <summary>
    /// Sorts the items of the collection in ascending order according to a key.
    /// </summary>
    /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
    /// <param name="keySelector">A function to extract a key from an item.</param>
    public void Sort<TKey>(Func<T, TKey> keySelector)
    {
        InternalSort(Items.OrderBy(keySelector));
    }

    /// <summary>
    /// Sorts the items of the collection in descending order according to a key.
    /// </summary>
    /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
    /// <param name="keySelector">A function to extract a key from an item.</param>
    public void SortDescending<TKey>(Func<T, TKey> keySelector)
    {
        InternalSort(Items.OrderByDescending(keySelector));
    }

    /// <summary>
    /// Sorts the items of the collection in ascending order according to a key.
    /// </summary>
    /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
    /// <param name="keySelector">A function to extract a key from an item.</param>
    /// <param name="comparer">An <see cref="IComparer{T}"/> to compare keys.</param>
    public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
    {
        InternalSort(Items.OrderBy(keySelector, comparer));
    }

    /// <summary>
    /// Moves the items of the collection so that their orders are the same as those of the items provided.
    /// </summary>
    /// <param name="sortedItems">An <see cref="IEnumerable{T}"/> to provide item orders.</param>
    private void InternalSort(IEnumerable<T> sortedItems)
    {
        var sortedItemsList = sortedItems.ToList();

        foreach (var item in sortedItemsList)
        {
            Move(IndexOf(item), sortedItemsList.IndexOf(item));
        }
    }

    #endregion // Sorting
}

我喜欢覆盖它,因为它允许我向它添加额外的功能,例如
IndexOf
AddRange
/
RemoveRange

您也可以使用
CollectionViewSource.GetDefaultView
ListCollectionView
为您进行排序,但是你也必须为所有子集合设置它。我使用linq查询将列表展平,以查找所有子项并设置排序

foreach (var structure in Model.Structures.Flatten(t => t.SubItems))
{
    var view = CollectionViewSource
        .GetDefaultView(structure.SubItems) as ListCollectionView;

    if (view != null)
    {
        view.CustomSort = (x,y) => string.Compare( x, y );
    }
}
别处

public static IEnumerable<T> Flatten<T>(
    this IEnumerable<T> list, Func<T, IEnumerable<T>> subitems)
{
    foreach (T child in list)
    {
        yield return child;

        foreach (T other in Flatten(subitems(child), subitems))
        {
            yield return other;
        }
    }
}
公共静态IEnumerable展平(
此IEnumerable列表,Func子项)
{
foreach(列表中的T子级)
{
退换子女;
foreach(展平中的T其他(子项(子项),子项))
{
其他收益率;
}
}
}

我开发了一个视图模型库,它可以做很多事情,包括让您按排序顺序显示层次结构数据。中描述了该库。这篇文章没有包含排序示例,但是您可以轻松地修改Demo2的视图模型,对其层次数据进行排序。只需执行以下操作:

  • 传递给
    SampleTreeNodePM
    的基本构造函数的三个布尔参数中的第一个参数指示视图模型集合是否应使用与域模型集合相同的索引。将此值更改为
    false
  • DesiredPosition
    方法覆盖返回值的最后一个参数是一个布尔值,指示是否对视图模型集合进行排序。将此值更改为
    true
  • 从上一步开始,现在需要修改域模型对象,
    SampleTreeNode
    ,以实现
    IComparable
    CompareTo
    方法只需将作业委托给
    Name
    string属性:

    public int CompareTo( SampleTreeNode other )
    {
        return Name.CompareTo( other.Name );
    }
    
  • 关于如您的问题所述的“动态”更新位置,只需在进行更改后调用我的库的
    Hierarchy Presentation Model.UpdatePosition
    方法即可

    public int CompareTo( SampleTreeNode other )
    {
        return Name.CompareTo( other.Name );
    }