Я не уверен, что вас заинтересует использование стороннего элемента управления, но у меня было ТОЧНО ТО ЖЕ требование, которое требовалось отображать данные иерархически, отображая повторяющиеся значения как единое целое со сворачиваемыми узлами (например, деревьями). Однако элементы управления Tree не привязаны к данным и все еще нуждаются в достаточном количестве кода. Но этот стиль построения дерева на основе ненормализованных данных может быть легко реализован с помощью DataBinding. Я использовал FlexGrid для привязки DataBable к DataTable, и ему просто нужно было несколько строк кода, чтобы ТОЧНО отобразить то, что вам нужно, хотя и на основе стороннего элемента управления.
Я использовал элемент управления ComponentOne FlexGrid и использовал его функцию «SubTotal» для генерации иерархических данных. Я вставляю приведенный ниже код на всякий случай, если вы заинтересованы в использовании ComponentOne FlexGrid. Вы можете скачать демонстрационную копию и проверить.
// Showing master policy in GROUPS
// -----------------------------------------------------------------------------------
// set tree mode to show settings in GROUPS
flxAvailableSettings.Tree.Style = TreeStyleFlags.Simple;
// show outline tree on column 1.
flxAvailableSettings.Tree.Column = 0;
flxAvailableSettings.Cols[0].Visible = true;
flxAvailableSettings.Cols[0].Width = 15;
flxAvailableSettings.AllowMerging = AllowMergingEnum.Nodes;
// subtotal on column 1, outline level 0
flxAvailableSettings.Subtotal(AggregateEnum.None, 0, 0, 0, "{0}");
// use owner draw to suppress repeating group names in Non-Node rows
flxAvailableSettings.DrawMode = DrawModeEnum.OwnerDraw;
flxAvailableSettings.OwnerDrawCell += new C1.Win.C1FlexGrid.OwnerDrawCellEventHandler(flxAvailableSettings_OwnerDrawCell);
// done, autosize columns to finish
flxAvailableSettings.AutoSizeCols();
// -----------------------------------------------------------------------------------
private void flxAvailableSettings_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)
{
if (!flxAvailableSettings.Rows[e.Row].IsNode && flxAvailableSettings.Cols[e.Col].Name == "PolicyGroup")
e.Text = "";
}
Строка flxAvailableSettings.Subtotal (AggregateEnum.None, 0, 0, 0, "{0}") генерирует группы деревьев, хотя мне нужно было группировать по одному столбцу, вы можете использовать группы по нескольким столбцам. Просто обратитесь к их документам на Subtotalling.
Надеюсь, это поможет.