WPF TreeView HierarchicalDataTemplate de liaison de l'objet, avec de multiples collections enfant
Je suis en train d'essayer d'obtenir un TreeView
pour lier ma collection de sorte que tous les groupes imbriqués groupes et chaque groupe d'entrée.
Comment puis-je utiliser le HierarchicalDataTemplate
de sorte que le TreeView
traitera à la fois des sous-groupes et les Entrées de collection?
Groupes montrent des sous-groupes et inscriptions:
Example:
Group1
--Entry
--Entry
Group2
--Group4
----Group1
------Entry
------Entry
----Entry
----Entry
--Entry
--Entry
Group3
--Entry
--Entry
Objets:
namespace TaskManager.Domain
{
public class Entry
{
public int Key { get; set; }
public string Name { get; set; }
}
}
namespace TaskManager.Domain
{
public class Group
{
public int Key { get; set; }
public string Name { get; set; }
public IList<Group> SubGroups { get; set; }
public IList<Entry> Entries { get; set; }
}
}
Données de Test:
namespace DrillDownView
{
public class TestData
{
public IList<Group> Groups = new List<Group>();
public void Load()
{
Group grp1 = new Group() { Key = 1, Name = "Group 1", SubGroups = new List<Group>(), Entries = new List<Entry>() };
Group grp2 = new Group() { Key = 2, Name = "Group 2", SubGroups = new List<Group>(), Entries = new List<Entry>() };
Group grp3 = new Group() { Key = 3, Name = "Group 3", SubGroups = new List<Group>(), Entries = new List<Entry>() };
Group grp4 = new Group() { Key = 4, Name = "Group 4", SubGroups = new List<Group>(), Entries = new List<Entry>() };
//grp1
grp1.Entries.Add(new Entry() { Key=1, Name="Entry number 1" });
grp1.Entries.Add(new Entry() { Key=2, Name="Entry number 2" });
grp1.Entries.Add(new Entry() { Key=3,Name="Entry number 3" });
//grp2
grp2.Entries.Add(new Entry(){ Key=4, Name = "Entry number 4"});
grp2.Entries.Add(new Entry(){ Key=5, Name = "Entry number 5"});
grp2.Entries.Add(new Entry(){ Key=6, Name = "Entry number 6"});
//grp3
grp3.Entries.Add(new Entry(){ Key=7, Name = "Entry number 7"});
grp3.Entries.Add(new Entry(){ Key=8, Name = "Entry number 8"});
grp3.Entries.Add(new Entry(){ Key=9, Name = "Entry number 9"});
//grp4
grp4.Entries.Add(new Entry(){ Key=10, Name = "Entry number 10"});
grp4.Entries.Add(new Entry(){ Key=11, Name = "Entry number 11"});
grp4.Entries.Add(new Entry(){ Key=12, Name = "Entry number 12"});
grp4.SubGroups.Add(grp1);
grp2.SubGroups.Add(grp4);
Groups.Add(grp1);
Groups.Add(grp2);
Groups.Add(grp3);
}
}
}
XAML:
<Window x:Class="DrillDownView.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TaskManager.Domain;assembly=TaskManager.Domain"
Title="Window2" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TreeView Name="GroupView" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Group}" ItemsSource="{Binding SubGroups}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Entry}" ItemsSource="{Binding Entries}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
XAML.CS:
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
LoadView();
}
private void LoadView()
{
TestData data = new TestData();
data.Load();
GroupView.ItemsSource = data.Groups;
}
}
- Très looong post et est absent de la question que vous avez probablement envie de poser.
- Comment puis-je utiliser le HierarchicalDataTemplate de sorte que l'arborescence est de traiter à la fois les sous-groupes et les Entrées de collection?
- reformaté et déplacé un peu de code autour de. Revenir si vous ne l'aimez pas. Travailler sur votre question..
- Est-ce une erreur? Configuration les éléments de l'arbre source une fois en YAML et une fois dans le code. le code que j'attends de soulever une exception. GroupView.ItemsSource = données.Les groupes
Vous devez vous connecter pour publier un commentaire.
Un
HierarchicalDataTemplate
est une manière de dire "c'est une façon de rendre ce type d'objet et voici une propriété qui peut être sondé pour trouver les nœuds enfants en vertu de cet objet'Par conséquent, vous avez besoin d'une propriété unique qui retourne les "enfants" de ce nœud.
par exemple (Si vous ne pouvez pas faire à la fois du Groupe et de l'Entrée de dériver à partir d'un même type de Nœud)
Ensuite, vous n'avez pas besoin d'un
HierDataTemplate
pour l'entrée depuis l'entrée n'ont pas d'enfants. Ainsi, le XAML doit être modifié pour utiliser les nouveaux Éléments de propriété et unDataTemplate
pour l'Entrée:Et voici ce que cela ressemble.
IEnumerable
sauf quand j'ai vraiment utiliser unIList
. En outre, cette méthode nous permet d'utiliser layield
mot-clé pour simplifier le code.Je pense que vous êtes la plupart du chemin... avec un petit peu de retravailler vous devriez obtenir ce travail assez facilement...
Je vous suggère de créer une base de classe abstraite (ou d'une interface, selon ce que vous préférez) et hériter de la/le mettre en œuvre pour à la fois le Groupe et la classe d'Entrée...
De cette façon, vous pouvez exposer une propriété au sein de votre Groupe d'objets
^à ce stade, vous pouvez prendre une décision si cela remplace vos listes de sous-groupes et les Entrées, ou simplement les ajoute ensemble et les renvoie dans le getter de la propriété...
Maintenant tous vous avez besoin est de remplir la collection d'Enfants avec l'un ou l'autre Groupe ou à l'Entrée des objets, et la
HierarchicalDataTemplate
rendra correctement lorsque les objets sont placés dans l'Arborescence..Une dernière pensée, si l'Entrée est toujours le "bas niveau" de l'arbre (c'est à dire n'a pas d'enfants), alors vous n'avez pas besoin de définir un
HierarchicalDataTemplate
pour l'Entrée de l'objet, unDataTemplate
suffira.Espère que cela aide 🙂
Ici est une variante de mise en œuvre de uasin gishu réponse qui renvoie un
IEnumerable
plutôt qu'unIList
, et rend l'utilisation de layield
mot-clé pour simplifier le code:Ce post m'a beaucoup aidé lors de la recherche d'une solution pour tha même question: http://blog.pmunin.com/2012/02/xaml-binding-to-compositecollection.html
à l'aide de MultiBinding et CompositeCollectionConverter..
/Matière Anders