2011-03-30 93 views
3

嗨我創建了這個小例子,我想擴展它以支持排序。展開Wpf Treeview支持排序

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

,我想有可能爲Treeview排序的Countries取決於SortOrder值。

它需要能夠在飛行中做到這一點。 因此,如果我例如更改SortOrder = 10的名稱=「丹麥」TreeView會自動反映這一點。

回答

5

我不認爲有一個TreeView的默認排序。您可以在將項目輸入集合之前對其進行排序,或者覆蓋ObservableCollection以包含Sort方法。

我將其覆蓋在我的項目之一:

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 
} 

你可以這樣調用類似

Countries.Sort(country => country.SortOrder); 

我喜歡覆蓋它梳理它,因爲它讓我把它作爲添加附加功能以及如IndexOfAddRange/RemoveRange

1

您也可以使用CollectionViewSource.GetDefaultViewListCollectionView爲你做排序,你也必須爲所有的子集合設置它。我使用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; 
     } 
    } 
} 
-1

我開發了一個視圖模型庫,它會做很多事情,包括讓你在顯示有序分層數據。該庫在this article中描述。該作品不包含排序示例,但您可以輕鬆修改Demo 2的視圖模型以對其分層數據進行排序。只要做到以下幾點:

  1. 首先傳遞給SampleTreeNodePM的基礎構造個Boolean參數表明,如果視圖模型集合應該使用相同的指數作爲域模型集合或沒有。將此值更改爲false
  2. DesiredPosition方法重寫的返回值的最後一個參數是一個布爾值,指示是否對視圖模型集合進行排序。將此值更改爲true
  3. 從上一步開始,您現在需要修改域模型對象SampleTreeNode以實施IComparable<SampleTreeNode>。該CompareTo方法的人只需要委派任務到Name字符串屬性:

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

關於更新「對飛」你的問題說,他們只是我的圖書館HierarchicalPresentationModel.UpdatePosition方法進行更改後的位置。