Одним из решений является создание базового класса, скажем, TreeNode, для элементов, которые будут размещены в дереве. Этот базовый класс имеет этот интерфейс:
public interface ITreeNode
{
ObservableCollection<ITreeNode> Children { get; set; }
string Name { get; set; }
ITreeNode Parent { get; set; }
void AddChild(ITreeNode child);
void RemoveChild(ITreeNode child);
}
Создайте классы, которые должны появиться в дереве, чтобы наследоваться от класса TreeNode:
public class DiscountGroup: TreeNode{};
public class SubGroup: TreeNode {}
public class ArticleGroup: TreeNode{}
Затем определите корень для вашего дерева, например:
Root = new TreeNode() {Name="Root"};
Добавить несколько веток
var dg1 = new DiscountedGroup(){Name = "DG1"};
var dg1 = new DiscountedGroup(){Name = "DG1"};
Root.AddChild(dg1);
Root.AddChild(dg2};
Добавить детей в ветки
dg1.AddChild(new ArticleGroup());
dg1.AddChild(new SubGroup());
dg2.AddChild(new ArticleGroup());
dg2.Add(new SubGroup());
Вы можете добавить столько слоев, сколько захотите. Затем в Xaml привяжите root.Children к своему TreeView.TreeViewItem.ItemsSource.
Убедитесь, что в Xaml => TreeViewItem.Resources у вас есть HierarchicalDataTemplate, определенный для объектов (или классов), у которых есть дочерние элементы (в противном случае просто используется DataTemplate), и используйте TreeViewItem.ItemTemplateSelector для определения правильного шаблона данных для каждого класса.
В этом есть больше деталей, я пытался объяснить в общем.