|
| 1 | +--- |
| 2 | +title: Filtering Child Rows in Self-referencing Hierarchy While Keeping Parent Row Visible |
| 3 | +description: Learn how to filter rows in a self-referencing hierarchical RadGridView while keeping parent rows visible when child rows match the filter condition. |
| 4 | +type: how-to |
| 5 | +page_title: Filtering Self-referencing Hierarchical RadGridView with Parent Row Visibility |
| 6 | +meta_title: Filtering Self-referencing Hierarchical RadGridView with Parent Row Visibility |
| 7 | +slug: grid-custom-filtering-self-referencing-hierarchy |
| 8 | +tags: gridview, ui-for-winforms, filtering, custom-filtering, self-referencing-hierarchy |
| 9 | +res_type: kb |
| 10 | +ticketid: 1700615 |
| 11 | +--- |
| 12 | + |
| 13 | +## Environment |
| 14 | + |
| 15 | +|Product Version|Product|Author| |
| 16 | +|----|----|----| |
| 17 | +|2025.3.812|RadGridView for WinForms|[Nadya Karaivanova](https://www.telerik.com/blogs/author/nadya-karaivanova)| |
| 18 | + |
| 19 | +## Description |
| 20 | + |
| 21 | +This knowledge base article shows how to filter rows in a self-referencing hierarchical RadGridView using custom filtering while keeping parent rows visible as long as any child rows match the filter condition. |
| 22 | + |
| 23 | +## Solution |
| 24 | + |
| 25 | +To achieve hierarchical filtering that retains parent rows when child rows match, use the **CustomFiltering** event and implement recursive filtering logic for the child rows. Follow these steps: |
| 26 | + |
| 27 | +1. Subscribe to the **CustomFiltering** event of the RadGridView. |
| 28 | +2. Implement a recursive method to evaluate each row and its child rows against the filter condition. |
| 29 | +3. Set the filtering logic so that parent rows remain visible if any matching child rows are found. |
| 30 | + |
| 31 | +### Example: Filtering Child Rows in Self-referencing Hierarchy While Keeping Parent Row Visible |
| 32 | + |
| 33 | +````C# |
| 34 | + |
| 35 | +public Form1() |
| 36 | +{ |
| 37 | + InitializeComponent(); |
| 38 | + |
| 39 | + this.radGridView1.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; |
| 40 | + this.radGridView1.DataSource = CreateDataSource(); |
| 41 | + |
| 42 | + this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "ID", "ParentID"); |
| 43 | + |
| 44 | + this.radGridView1.Columns["ID"].IsVisible = false; |
| 45 | + this.radGridView1.Columns["ParentID"].IsVisible = false; |
| 46 | + this.radGridView1.Columns["Size"].FormatString = "{0} MB"; |
| 47 | + |
| 48 | + this.radGridView1.EnableFiltering = true; |
| 49 | + this.radGridView1.MasterTemplate.EnableFiltering = true; |
| 50 | + this.radGridView1.EnableCustomFiltering = true; |
| 51 | + this.radGridView1.CustomFiltering += new GridViewCustomFilteringEventHandler(radGridView1_CustomFiltering); |
| 52 | + this.radTextBox1.TextChanged += RadTextBox1_TextChanged; |
| 53 | +} |
| 54 | + |
| 55 | +private void RadTextBox1_TextChanged(object sender, EventArgs e) |
| 56 | +{ |
| 57 | + this.radGridView1.MasterTemplate.Refresh(); |
| 58 | +} |
| 59 | + |
| 60 | +private void radGridView1_CustomFiltering(object sender, GridViewCustomFilteringEventArgs e) |
| 61 | + { |
| 62 | + string searchString = this.radTextBox1.Text; |
| 63 | + if (string.IsNullOrEmpty(searchString)) |
| 64 | + { |
| 65 | + e.Visible = true; |
| 66 | + e.Row.IsVisible = true; |
| 67 | + return; |
| 68 | + } |
| 69 | + |
| 70 | + string columnName_cellValue = e.Row.Cells["Name"].Value.ToString(); |
| 71 | + bool parentContains = false; |
| 72 | + foreach (var childRow in e.Row.ChildRows) |
| 73 | + { |
| 74 | + |
| 75 | + string text = childRow.Cells["Name"].Value?.ToString() ?? ""; |
| 76 | + if (childRow.ChildRows.Count> 0) |
| 77 | + { |
| 78 | + foreach (var innerRow in childRow.ChildRows) |
| 79 | + { |
| 80 | + text = innerRow.Cells["Name"].Value?.ToString() ?? ""; |
| 81 | + if (text.Contains( searchString)) |
| 82 | + { |
| 83 | + e.Visible = true; |
| 84 | + e.Row.IsVisible = true; |
| 85 | + parentContains = true; |
| 86 | + } |
| 87 | + else |
| 88 | + { |
| 89 | + e.Visible = false; |
| 90 | + e.Row.IsVisible = false; |
| 91 | + } |
| 92 | + } |
| 93 | + } |
| 94 | + else |
| 95 | + { |
| 96 | + if (text.Contains(searchString)) |
| 97 | + { |
| 98 | + e.Visible = true; |
| 99 | + e.Row.IsVisible = true; |
| 100 | + parentContains = true; |
| 101 | + } |
| 102 | + else |
| 103 | + { |
| 104 | + e.Visible = false; |
| 105 | + e.Row.IsVisible = false; |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + } |
| 110 | + |
| 111 | + if (!parentContains) |
| 112 | + { |
| 113 | + if (columnName_cellValue.Contains(searchString)) |
| 114 | + { |
| 115 | + |
| 116 | + e.Visible = true; |
| 117 | + e.Row.IsVisible = true; |
| 118 | + } |
| 119 | + else |
| 120 | + { |
| 121 | + e.Visible = false; |
| 122 | + e.Row.IsVisible = false; |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + e.Handled = true; |
| 127 | +} |
| 128 | + |
| 129 | +private static DataTable CreateDataSource() |
| 130 | +{ |
| 131 | + DataTable dataSource = new DataTable("fileSystem"); |
| 132 | + dataSource.Columns.Add("ID", typeof(int)); |
| 133 | + dataSource.Columns.Add("ParentID", typeof(int)); |
| 134 | + dataSource.Columns.Add("Name", typeof(string)); |
| 135 | + dataSource.Columns.Add("Date", typeof(DateTime)); |
| 136 | + dataSource.Columns.Add("Type", typeof(string)); |
| 137 | + dataSource.Columns.Add("Size", typeof(int)); |
| 138 | + |
| 139 | + dataSource.Rows.Add(1, null, "Program Files", DateTime.Now.AddDays(-100), "Folder", 5120); |
| 140 | + dataSource.Rows.Add(2, 1, "Visual Studio 2010", DateTime.Now.AddDays(-100), "Folder", 3220); |
| 141 | + dataSource.Rows.Add(3, 2, "bin", DateTime.Now.AddDays(-100), "Folder", 3220); |
| 142 | + dataSource.Rows.Add(4, 2, "READEME.txt", DateTime.Now.AddDays(-100), "Text Document", 3); |
| 143 | + |
| 144 | + dataSource.Rows.Add(5, 1, "Telerik RadControls", DateTime.Now.AddDays(-10), "Folder", 3120); |
| 145 | + dataSource.Rows.Add(6, 5, "Telerik UI for Winforms", DateTime.Now.AddDays(-10), "Folder", 101); |
| 146 | + dataSource.Rows.Add(7, 5, "Telerik UI for Silverlight", DateTime.Now.AddDays(-10), "Folder", 123); |
| 147 | + dataSource.Rows.Add(8, 5, "Telerik UI for WPF", DateTime.Now.AddDays(-10), "Folder", 221); |
| 148 | + dataSource.Rows.Add(9, 5, "Telerik UI for ASP.NET AJAX", DateTime.Now.AddDays(-10), "Folder", 121); |
| 149 | + |
| 150 | + dataSource.Rows.Add(10, 1, "Microsoft Office 2010", DateTime.Now.AddDays(-120), "Folder", 1230); |
| 151 | + dataSource.Rows.Add(11, 10, "Microsoft Word 2010", DateTime.Now.AddDays(-120), "Folder", 1230); |
| 152 | + dataSource.Rows.Add(12, 10, "Microsoft Excel 2010", DateTime.Now.AddDays(-120), "Folder", 1230); |
| 153 | + dataSource.Rows.Add(13, 10, "Microsoft Powerpoint 2010", DateTime.Now.AddDays(-120), "Folder", 1230); |
| 154 | + |
| 155 | + dataSource.Rows.Add(14, 1, "Debug Diagnostic Tools v1.0", DateTime.Now.AddDays(-400), "Folder", 2120); |
| 156 | + dataSource.Rows.Add(15, 1, "Designer's 3D Tools", DateTime.Now.AddDays(-500), "Folder", 1120); |
| 157 | + dataSource.Rows.Add(16, 1, "Communication", DateTime.Now.AddDays(-700), "Folder", 120); |
| 158 | + |
| 159 | + dataSource.Rows.Add(17, null, "My Documents", DateTime.Now.AddDays(-200), "Folder", 1024); |
| 160 | + dataSource.Rows.Add(18, 17, "Salaries.xlsx", DateTime.Now.AddDays(-200), "Excel File", 1); |
| 161 | + dataSource.Rows.Add(19, 18, "RecessionAnalysis.xlsx", DateTime.Now.AddDays(-200), "Excel File", 1); |
| 162 | + |
| 163 | + dataSource.Rows.Add(20, null, "Windows", DateTime.Now.AddDays(-100), "Folder", 10240); |
| 164 | + |
| 165 | + dataSource.Rows.Add(21, 20, "System32", DateTime.Now.AddDays(-220), "Folder", 510); |
| 166 | + dataSource.Rows.Add(22, 20, "assembly", DateTime.Now.AddDays(-20), "Folder", 240); |
| 167 | + |
| 168 | + dataSource.Rows.Add(23, 22, "System.Data.dll", DateTime.Now.AddDays(-20), "Assembly File", 4); |
| 169 | + dataSource.Rows.Add(24, 22, "System.Core.dll", DateTime.Now.AddDays(-20), "Assembly File", 2); |
| 170 | + dataSource.Rows.Add(25, 22, "System.Drawings.dll", DateTime.Now.AddDays(-20), "Assembly File", 3); |
| 171 | + dataSource.Rows.Add(26, 22, "Telerik.WinControls.UI.dll", DateTime.Now.AddDays(-20), "Assembly File", 5); |
| 172 | + |
| 173 | + dataSource.Rows.Add(27, null, "Users", DateTime.Now.AddDays(-100), "Folder", 5512); |
| 174 | + dataSource.Rows.Add(28, 27, "Administrator", DateTime.Now.AddDays(-100), "Folder", 1512); |
| 175 | + dataSource.Rows.Add(29, 27, "Guest", DateTime.Now.AddDays(-100), "Folder", 2512); |
| 176 | + dataSource.Rows.Add(30, 27, "User1", DateTime.Now.AddDays(-100), "Folder", 3512); |
| 177 | + |
| 178 | + dataSource.Rows.Add(31, null, "Share", DateTime.Now.AddDays(-50), "Folder", 15360); |
| 179 | + dataSource.Rows.Add(32, 31, "Photos", DateTime.Now.AddDays(-50), "Folder", 360); |
| 180 | + dataSource.Rows.Add(33, 32, "Flowers.JPG", DateTime.Now.AddDays(-50), "JPEG File", 1); |
| 181 | + dataSource.Rows.Add(34, 32, "Panda.GIF", DateTime.Now.AddDays(-50), "GIF File", 3); |
| 182 | + dataSource.Rows.Add(35, 32, "Landscape.png", DateTime.Now.AddDays(-50), "PNG File", 4); |
| 183 | + |
| 184 | + dataSource.Rows.Add(36, null, "Music", DateTime.Now.AddDays(-2), "Folder", 0); |
| 185 | + dataSource.Rows.Add(37, 36, "Mozart", DateTime.Now.AddDays(-3), "Folder", 0); |
| 186 | + dataSource.Rows.Add(38, 36, "Pavarotti", DateTime.Now.AddDays(-40), "Folder", 0); |
| 187 | + dataSource.Rows.Add(39, 36, "AC/DC", DateTime.Now.AddDays(-50), "Folder", 0); |
| 188 | + dataSource.Rows.Add(40, 36, "Queen", DateTime.Now.AddDays(-8), "Folder", 0); |
| 189 | + |
| 190 | + dataSource.Rows.Add(41, null, "Boot.ini", DateTime.Now.AddDays(-10), "INI File", 0); |
| 191 | + |
| 192 | + return dataSource; |
| 193 | +} |
| 194 | + |
| 195 | +```` |
| 196 | + |
| 197 | +## See Also |
| 198 | +* [Custom Filtering](https://docs.telerik.com/devtools/winforms/controls/gridview/features/filtering/custom-filtering) |
0 commit comments