or
Form1.cs:
using System;using System.Collections.Generic;using System.Windows.Forms;using Telerik.WinControls.UI;namespace GridWithIndexedHierarchySpike{ public partial class Form1 : Form { public Form1() { InitializeComponent(); dummyGridView.Dock = DockStyle.Fill; dummyGridView.Parent = this; dummyGridView.BringToFront(); dummyGridView.MultiSelect = true; dummyGridView.UseScrollbarsInHierarchy = true; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); GridViewTemplate childTemplate = CreateChildTemplate(); dummyGridView.Templates.Add(childTemplate); childTemplate.HierarchyDataProvider = new GridViewEventDataProvider(childTemplate); //grid events dummyGridView.RowSourceNeeded += gridView_RowSourceNeeded; dummyGridView.CreateRowInfo += CreateGridViewHierarchyRowInfoWithCustomSelectBehavior; dummyGridView.Templates[0].CreateRowInfo += CreateGridViewDataRowInfoWhitCustomSelectBehavior; //databind dummyGridView.DataSource = CreateDummyData(5); } void gridView_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e) { List<SomeData> data = CreateDummyData(2); foreach (SomeData someData in data) { GridViewRowInfo row = e.Template.Rows.NewRow(); row.Cells[0].Value = someData.Name; row.Cells[1].Value = someData.SomeDataId; row.Cells[2].Value = someData.ParentDataId; e.SourceCollection.Add(row); } } private static void CreateGridViewHierarchyRowInfoWithCustomSelectBehavior(object sender, GridViewCreateRowInfoEventArgs e) { if (e.RowInfo is GridViewHierarchyRowInfo) { e.RowInfo = new MultiSelectGridViewHierarchyRowInfo(e.ViewInfo); } } private static void CreateGridViewDataRowInfoWhitCustomSelectBehavior(object sender, GridViewCreateRowInfoEventArgs e) { if (e.RowInfo is GridViewDataRowInfo) { e.RowInfo = new MultiSelectGridViewDataRowInfo(e.ViewInfo); } } private GridViewTemplate CreateChildTemplate() { var template = new GridViewTemplate {AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill}; var namecolumn = new GridViewTextBoxColumn("Name"); var idColumn = new GridViewTextBoxColumn("ID"); var parentColumn = new GridViewTextBoxColumn("Parent"); template.Columns.AddRange(namecolumn, idColumn, parentColumn); return template; } private static List<SomeData> CreateDummyData(int nbrRows) { var data = new List<SomeData>(); var someData = new SomeData { Name = Guid.NewGuid().ToString(), ParentDataId = null, SomeDataId = 0 }; data.Add(someData); for (int i = 1; i <= nbrRows - 1; i++) { var someChildData = new SomeData() { Name = Guid.NewGuid().ToString(), ParentDataId = someData.SomeDataId, SomeDataId = i }; data.Add(someChildData); } return data; } public class SomeData { public int SomeDataId { get; set; } public int? ParentDataId { get; set; } public string Name { get; set; } } }}
CustomRowInfos.cs:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Telerik.WinControls.UI;namespace GridWithIndexedHierarchySpike{ /// <summary> /// Hierarchy row with custom select behavior. /// When the row is (de)selected, all child rows are (de)selected /// </summary> public class MultiSelectGridViewHierarchyRowInfo : GridViewHierarchyRowInfo { public static bool ParentSilentUpdate; public static bool OverrideChildSelection; public MultiSelectGridViewHierarchyRowInfo(GridViewInfo owner) : base(owner) { ParentSilentUpdate = false; } protected override bool SetBooleanProperty(string propertyName, int propertyKey, bool value) { bool result = base.SetBooleanProperty(propertyName, propertyKey, value); if (result && propertyName == "IsSelected") { if (!MultiSelectGridViewDataRowInfo.ChildSilentUpdate) { //parent row is selected/deselected; SelectChildRows(value); } } return result; } private void SelectChildRows(bool isSelected) { if (OverrideChildSelection) return; ParentSilentUpdate = true; foreach (MultiSelectGridViewDataRowInfo row in this.ChildRows) { row.IsSelected = isSelected; } ParentSilentUpdate = false; } } /// <summary> /// Data row with custom select behavior. /// If the row is a child row of a parent row then /// the parent row is selected when the child rows (or one of its siblings) is selected, /// otherwise the parent row is deselected. /// </summary> public class MultiSelectGridViewDataRowInfo : GridViewDataRowInfo { public static bool ChildSilentUpdate; public MultiSelectGridViewDataRowInfo(GridViewInfo viewInfo) : base(viewInfo) { ChildSilentUpdate = false; } public object OriginalBoundItem { get; set; } protected override bool SetBooleanProperty(string propertyName, int propertyKey, bool value) { bool result = base.SetBooleanProperty(propertyName, propertyKey, value); if (result && propertyName == "IsSelected") { if (!MultiSelectGridViewHierarchyRowInfo.ParentSilentUpdate) { //child row is selected SelectParentRow(value); } } return result; } private void SelectParentRow(bool isSelected) { var parent = Parent as MultiSelectGridViewHierarchyRowInfo; if (parent == null) return; ChildSilentUpdate = true; if (isSelected) { parent.IsSelected = true; } else { //check if there are other rows bool selected = GetParentRowSelection(parent); parent.IsSelected = selected; } ChildSilentUpdate = false; } private bool GetParentRowSelection(MultiSelectGridViewHierarchyRowInfo parent) { //if there is one selected child row, return true return parent.ChildRows.Cast<MultiSelectGridViewDataRowInfo>().Any(row => row != this && row.IsSelected); } }}public partial class Form1 : Form { public Form1() { InitializeComponent(); Bind(GetList()); Print("Before show"); } public void Bind( List<DictionaryEntry> p_List) { radDropDownList1.ValueMember = "Key"; radDropDownList1.DisplayMember = "Value"; radDropDownList1.DataSource = p_List; radDropDownList1.SelectedIndex = -1; radDropDownList1.SelectedItem = null; radDropDownList1.SelectedValue = null; } private List<DictionaryEntry> GetList() { return new List<DictionaryEntry> { new DictionaryEntry(0, "Entry 0"), new DictionaryEntry(1, "Entry 1") }; } private void button1_Click(object sender, EventArgs e) { Bind(GetList()); Print("rebind"); } private void Print(string p_Message) { richTextBox1.AppendText(String.Format("{2}\nSelectedIndex = {0}\nSelectedValue = {1}\n\n", radDropDownList1.SelectedIndex, radDropDownList1.SelectedValue, p_Message)); } private void Form1_Shown(object sender, EventArgs e) { Print("OnShow"); } private void button2_Click(object sender, EventArgs e) { Print("Print state"); } }private static HtmlFormatProvider _htmlFormatProvider; private static void InitHtmlFormatProvider() { _htmlFormatProvider = new HtmlFormatProvider(); var htmlExportSettings = new HtmlExportSettings(); htmlExportSettings.DocumentExportLevel = DocumentExportLevel.Fragment; _htmlFormatProvider.ExportSettings = htmlExportSettings; } private void commandBarButtonLoad_Click(object sender, EventArgs e) { string text = File.ReadAllText(@"c:\temp\RichText.txt"); RadDocument document = _htmlFormatProvider.Import(text); radRichTextBox1.Document = document; } private void commandBarButtonSave_Click(object sender, EventArgs e) { string html = _htmlFormatProvider.Export(radRichTextBox1.Document); File.WriteAllText(@"c:\temp\RichText.txt", html); }