2010-02-11 14 views
7

Próbuję uzyskać widok drzewa, aby zgrupować kolekcję podobnych elementów według ich stanu. Aby zachować rzeczy ogólne, mój obiekt hierarchia może wyglądać następująco:Grupowanie obiektów podrzędnych w drzewie WPF TreeView

  • Przedmioty
    • Object grupa nr 1
      • Przedmiot # 1 (typ 'A')
      • Pozycja nr 2 (Typ 'A')
      • Pozycja nr 3 (typu 'B')
      • Przedmiot # 4 (typu 'B')

Teraz moje TreeView pokazuje te przedmioty dokładnie jak model obiektowy, ale to, co chciałbym zrobić to wstawić węzeł TreeView dla każdego typu obiektu tak, że będzie wyglądać następująco:

  • Przedmioty
    • obiektu grupy # 1
      • typu A
        • Pozycja nr 1
        • Przedmiot # 2
      • Typ B
        • Pozycja nr 3
        • Przedmiot # 4

Widziałem w podobnym pytaniu tutaj, że ktoś polecił mieć dwa oddzielne HierarchicalDataTemplates, więc stworzyłem jeden dla "grupy obiektów nr 1", który zawiera TreeView z listą typów, ale jest to naprawdę niezgrabne, ponieważ jest to całe oddzielne TreeView wewnątrz niektórych węzłów. Próbuję również użyć CollectionViewSource, aby odfiltrować elementy w każdej kategorii, ale to nie robi mi wiele dobrego, ponieważ nie mogę wymyślić, jak je wyświetlić.

Domyślam się, że moje pytanie sprowadza się do tego: jak utworzyć grupę HierarchicalDataTemplate dla dzieci? Gdyby ktoś wskazał mi właściwy kierunek, doceniłbym to bardzo.

Mogę napisać kod, jeśli ktoś chce zobaczyć, ale ja naprawdę próbuję po prostu dowiedzieć się, jak zrobić to, co chcę, więc mój kod jest po prostu dość prosty widok drzewa databound teraz.

Odpowiedz

5

Zapoznaj się z artykułem this autorstwa Sumi. Jestem pewien, że ci to pomoże.

+0

To jest dokładnie to, co muszę zobaczyć. Dzięki. – aalex675

0

AFAIK, HierarchicalDataTemplate nie może grupować swoich dzieci.

Widok powinien pokazywać wszystko, co robi, bez wchodzenia w typy/grupy obiektów ... Dlaczego nie stworzysz tych grup w swoim modelu obiektowym?

I widok po prostu dostać smth jak:

public interface ITreeNode 
{ 
    string Title; 
    IList<ITreeNode> ChildNodes; 
} 

i wyświetlić go za pomocą HierarchicalDataTemplate.

7

Możesz osiągnąć ten efekt wiążąc ItemsSource na swoim HierarchicalDataTempalate przy użyciu IValueConverter. Ten konwerter jest po prostu wykonuje następujące operacje:

public class MyConverter : IValueConverter 
{ 
    public object Convert(object value, ...) 
    { 
    return 
     from item in (IEnumerable<MyItem>)value 
     group item by item.Type into g 
     select new { Type = item.Type, Items = g }; 
    } 
    ... 
} 

Teraz twój HierarchcialDataTemplate może być następująca:

<HierarchicalDataTemplate ItemsSource="{Binding SomePath, Converter={x:Static local:MyConverter}"> 

    <HierarchicalDataTemplate.ItemTemplate> 
    <HierarchicalDataTemplate 
     ItemsSource="{Binding Items}" 
     TargetType="{x:Type local:MyItem}" 

     ItemTemplate="{StaticResource MyItemTemplate}"> 
     <!-- may omit ItemTemplate in prior line to use implicit template --> 

     <TextBlock Text="{Binding Type}" /> <!-- Header for type --> 

    </HierarchicalDataTemplate> 
    </HierarchicalDataTemplate.ItemTemplate> 

    <!-- header for "Object Group #1" --> 

</HierarchicalDataTemplate> 
+1

'wybierz nowy {Type = item.Type, Items = g};' nie kompiluje; może 'select new {Type = g.First(). Type, Items = g};'? – arolson101

+1

'wybierz nowy {Type = g.Key, Items = g}' works – arolson101

0

Jeśli jest to prosty metoda grupowania z płaskiego Kolekcja dla celów wyświetlania że szukasz może użycie "CollectionViewSource" będzie bardziej odpowiednie. Używanie LINQ może stać się koszmarem z powodu propagacji zdarzenia Zmiana właściwości/kolekcji.

<CollectionViewSource x:Key="GroupedItems" Source="{Binding ItemsSource, ElementName=My_UserControl}"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="Type" Converter="{StaticResource GroupingConverter}" /> 
    </CollectionViewSource.GroupDescriptions> 
    <CollectionViewSource.SortDescriptions> 
     <scm:SortDescription PropertyName="Date"/> 
    </CollectionViewSource.SortDescriptions> 
</CollectionViewSource> 

<HierarchicalDataTemplate x:Key="GroupDataTemplate" ItemsSource="{Binding Items}" > 
    <TextBlock Text="{Binding Name}" /> 
</HierarchicalDataTemplate> 

<TreeView x:Name="ItemHolder" x:FieldModifier="private" 
    ItemsSource="{Binding Source={StaticResource GroupedItems}, Path=Groups}" 
... />