I have a hierarchical grid with some childs. Now I need to set programatically the right Row and Column in the grid (after the user has clicked somewhere). In the normal grid this is easy and goes just this:
grid.CurrentRow = grid.Rows[rowIndex];<br>grid.CurrentColumn = grid.Columns[fieldIndex];But when the cell is in one of the child grids it gets complicated. After searching the grid I know in which child in which row it is. Since the rows in each child grids are also zerobased, my only solution to set the correct line is this one (if it is in the first level of the hierarchy):
grid.CurrentRow = selectedRow.ViewInfo.ParentRow.ChildRows[rowIndex];But I cannot get set the correct column.
grid.CurrentColumn = selectedRow.ViewInfo.ParentRow.ChildRows[rowIndex].ViewTemplate.Columns[fieldIndex];The expression on the right side returns the correct index. But assigning to grid.CurrentColumn doesn't change anything. No error, but also no setting of the currentcolumn.
- Can anybody help how to set this correctly?
- Is there a more elegant generic solution to get to right child? For now I would just need to hardcode the access to each child level.
Thanks,
Michael
16 Answers, 1 is accepted
I've just tried this on one of our existing Hierarchy grids, and on SelectionChanged of the Grid
private void GridView_SelectionChanged(System.Object sender, System.EventArgs e){ if (this.GridView.MasterTemplate.SelectedRows.Count > 0) { if (this.GridView.MasterTemplate.SelectedRows(0).ViewInfo.ParentRow != null) { GridView.CurrentRow = this.GridView.MasterTemplate.SelectedRows(0).ViewInfo.ParentRow.ChildRows(0); GridView.CurrentColumn = this.GridView.MasterTemplate.SelectedRows(0).ViewInfo.ParentRow.ChildRows(0).ViewTemplate.Columns(2); MessageBox.Show(GridView.CurrentColumn.HeaderText); } }}This has set the Cell to the third column of the first child row.
Richard
Just a bit of an update. You've really done most of the hard work by finding out which row and column you need to get to, but after populating, I could also do this.
this.GridView.Rows(0).IsExpanded = true; // knowing that Row0 existsthis.GridView.Rows(0).ChildRows(1).IsSelected = true; // Knowing that it has at least 2 child rowsthis.GridView.Rows(0).ChildRows(1).Cells(2).IsSelected = true; // knowing that it has at least 2 columns// Display the header text of the column, of the selected cellMessageBox.Show(this.GridView.Rows(0).ChildRows(1).Cells(2).ColumnInfo.HeaderText);// Display the cell valueMessageBox.Show(this.GridView.Rows(0).ChildRows(1).Cells(2).Value.ToString());Richard
Hello
I asked a question here and wanted to search the grids as mentioned in demo Telerik for WinForms Q3 2010 (Custom Filtering).
Mr Richard Slade replied me and gave this thread to read but I could not find my answer.
I am looking for a way to search the child grids as it is shown for a non-hierarchical grid in Demo. I want to show those records that have the exact searched text even in their child grids.
Is there any way to do that?
Thanks
As per the other thread to which you refer, the filtering mechanism for both the master template and child template is the same and you would need to itterate over the rows as detailed. Please see this link on Custom Filtering which you can use to help you build your custom filter and apply the principal to both the master and child template.
Regards,
Richard
Hello Richard
Thank you for reply
I tried this code to iterate over the master template rows But I could not change it in a way to go to child templates.\
for (int i = 0; i < this.personDataGridView.ColumnCount; i++) { string text = e.Row.Cells[i].Value.ToString(); if (text.IndexOf(textBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) { e.Visible = true; e.Row.Cells[i].Style.CustomizeFill = true; e.Row.Cells[i].Style.DrawFill = true; e.Row.Cells[i].Style.BackColor = Color.FromArgb(201, 252, 254); } else { e.Row.Cells[i].Style.Reset(); e.Row.InvalidateRow(); } } }thanks a lot
Hello Richard
I used this code to access to child templates and it works fine.(thank you for your help)
if (string.IsNullOrEmpty(textBox1.Text)) { e.Visible = true; for (int i = 0; i < personDataGridView.ColumnCount; i++) { e.Row.Cells[i].Style.Reset(); e.Row.InvalidateRow(); } return; } e.Visible = false; for (int i = 0; i < this.gridViewTemplate1.ColumnCount; i++) { string text = e.Row.Cells[i].Value.ToString(); if (text.IndexOf(textBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) { e.Visible = true; e.Row.Cells[i].Style.CustomizeFill = true; e.Row.Cells[i].Style.DrawFill = true; e.Row.Cells[i].Style.BackColor = Color.FromArgb(201, 252, 254); } else { bool chk = false; for (int j = 0; j < personDataGridView.Templates.Count; j++) { for (int k = 0; k < personDataGridView.Templates[j].RowCount; k++) for (int r = 0; r < personDataGridView.Templates[j].ColumnCount; r++) { if (e.Template.Templates[j].Rows[k].Cells[r].Value != null) { string text2 = e.Template.Templates[j].Rows[k].Cells[r].Value.ToString(); if (text2.IndexOf(textBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) { chk = true; e.Visible = true; e.Template.Templates[j].Rows[k].Cells[r].Style.CustomizeFill = true; e.Template.Templates[j].Rows[k].Cells[r].Style.DrawFill = true; e.Template.Templates[j].Rows[k].Cells[r].Style.BackColor = Color.FromArgb(201, 252, 254); } else { e.Template.Templates[j].Rows[k].Cells[r].Style.Reset(); e.Template.Templates[j].Rows[k].Cells[r].RowInfo.InvalidateRow(); } } } } if (chk == false) { e.Row.Cells[i].Style.Reset(); e.Row.InvalidateRow(); } } }Now I want to HIDE the master template rows that does not contain the searched text in their child templates.
is there a solution for that?
Ragards
As far as I'm aware, you cannot do this. The child rows are connected to the parent rows, and therefore if you hide the parent, you will be hiding the children.
Regards,
Richard
Hello
I suppose I could not explain it well.
I want to Hide the master template rows and their child templates too, not Only the master template rows.
I want to search the rows and their child templates and if Some rows (and its child template) do not contain the searched text, they should become hidden (I mean the rows and their child templates).
I hope you understand what I mean.
Regards
Here is a brief example. It has been adapted from the one found on the demos on your PC.
Designer File
namespace RadGridView_hierarchy_C { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { Telerik.WinControls.UI.GridViewDecimalColumn gridViewDecimalColumn5 = new Telerik.WinControls.UI.GridViewDecimalColumn(); Telerik.WinControls.UI.GridViewDecimalColumn gridViewDecimalColumn6 = new Telerik.WinControls.UI.GridViewDecimalColumn(); Telerik.WinControls.UI.GridViewTextBoxColumn gridViewTextBoxColumn2 = new Telerik.WinControls.UI.GridViewTextBoxColumn(); Telerik.WinControls.UI.GridViewDecimalColumn gridViewDecimalColumn7 = new Telerik.WinControls.UI.GridViewDecimalColumn(); Telerik.WinControls.UI.GridViewDecimalColumn gridViewDecimalColumn8 = new Telerik.WinControls.UI.GridViewDecimalColumn(); this.radGridView1 = new Telerik.WinControls.UI.RadGridView(); this.radTextBox1 = new Telerik.WinControls.UI.RadTextBox(); ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.radTextBox1)).BeginInit(); this.SuspendLayout(); // // radGridView1 // this.radGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.radGridView1.Location = new System.Drawing.Point(12, 35); // // radGridView1 // gridViewDecimalColumn5.DecimalPlaces = 0; gridViewDecimalColumn5.FieldName = "ID"; gridViewDecimalColumn5.FormatString = ""; gridViewDecimalColumn5.HeaderText = "ID"; gridViewDecimalColumn5.IsVisible = false; gridViewDecimalColumn5.Name = "ID"; gridViewDecimalColumn5.TextAlignment = System.Drawing.ContentAlignment.MiddleRight; gridViewDecimalColumn6.DecimalPlaces = 0; gridViewDecimalColumn6.FieldName = "ID2"; gridViewDecimalColumn6.FormatString = ""; gridViewDecimalColumn6.HeaderText = "ID2"; gridViewDecimalColumn6.IsVisible = false; gridViewDecimalColumn6.Name = "ID2"; gridViewDecimalColumn6.TextAlignment = System.Drawing.ContentAlignment.MiddleRight; gridViewTextBoxColumn2.FieldName = "Name"; gridViewTextBoxColumn2.FormatString = ""; gridViewTextBoxColumn2.HeaderText = "Name"; gridViewTextBoxColumn2.Name = "Name"; gridViewTextBoxColumn2.ReadOnly = true; gridViewTextBoxColumn2.Width = 100; gridViewDecimalColumn7.FieldName = "Price"; gridViewDecimalColumn7.FormatString = ""; gridViewDecimalColumn7.HeaderText = "Price"; gridViewDecimalColumn7.Name = "Price"; gridViewDecimalColumn7.TextAlignment = System.Drawing.ContentAlignment.MiddleRight; gridViewDecimalColumn7.Width = 150; gridViewDecimalColumn8.DecimalPlaces = 0; gridViewDecimalColumn8.FieldName = "Qty"; gridViewDecimalColumn8.FormatString = ""; gridViewDecimalColumn8.HeaderText = "Qty"; gridViewDecimalColumn8.Maximum = new decimal(new int[] { 100, 0, 0, 0}); gridViewDecimalColumn8.Minimum = new decimal(new int[] { 1, 0, 0, 0}); gridViewDecimalColumn8.Name = "Qty"; gridViewDecimalColumn8.TextAlignment = System.Drawing.ContentAlignment.MiddleRight; gridViewDecimalColumn8.Width = 150; this.radGridView1.MasterTemplate.Columns.AddRange(new Telerik.WinControls.UI.GridViewDataColumn[] { gridViewDecimalColumn5, gridViewDecimalColumn6, gridViewTextBoxColumn2, gridViewDecimalColumn7, gridViewDecimalColumn8}); this.radGridView1.Name = "radGridView1"; this.radGridView1.Size = new System.Drawing.Size(604, 379); this.radGridView1.TabIndex = 0; this.radGridView1.Text = "radGridView1"; this.radGridView1.CustomFiltering += new Telerik.WinControls.UI.GridViewCustomFilteringEventHandler(this.radGridView1_CustomFiltering); // // radTextBox1 // this.radTextBox1.Location = new System.Drawing.Point(12, 9); this.radTextBox1.Name = "radTextBox1"; this.radTextBox1.NullText = "enter search string"; this.radTextBox1.Size = new System.Drawing.Size(525, 20); this.radTextBox1.TabIndex = 1; this.radTextBox1.TabStop = false; this.radTextBox1.TextChanged += new System.EventHandler(this.radTextBox1_TextChanged); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(628, 426); this.Controls.Add(this.radTextBox1); this.Controls.Add(this.radGridView1); this.Name = "Form1"; this.Text = "Form1"; ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.radTextBox1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private Telerik.WinControls.UI.RadGridView radGridView1; private Telerik.WinControls.UI.RadTextBox radTextBox1; } } Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Telerik.WinControls; using Telerik.WinControls.UI; using Telerik.WinControls.RadControlSpy; using System.Globalization; using Telerik.WinControls.UI.Export; using Telerik.WinControls.Data; namespace RadGridView_hierarchy_C { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.Load += new System.EventHandler(this.Form1_Load); } private void Form1_Load(object sender, EventArgs e) { List<Person> People = new List<Person>(); List<Car> Cars = new List<Car>(); // load primary data source People.Add(new Person(1, 101, "Bob", 204.50M, 1)); People.Add(new Person(2, 102, "Rob", 208.00M, 1)); People.Add(new Person(3, 103, "Eric", 300.00M, 1)); this.radGridView1.DataSource = People; GridViewTemplate carTemplate = new GridViewTemplate(); Cars.Add(new Car(101, 1, "Ford", 100.50M, 1)); Cars.Add(new Car(102, 2, "BMW", 104, 1)); Cars.Add(new Car(102, 6, "BMW", 104, 1)); Cars.Add(new Car(102, 7, "BMW", 104, 1)); Cars.Add(new Car(102, 3, "Mazda", 100, 1)); Cars.Add(new Car(102, 8, "Mazda", 100, 1)); Cars.Add(new Car(102, 4, "Merc", 100, 1)); Cars.Add(new Car(103, 5, "Honda", 100, 1)); carTemplate.DataSource = Cars; // Now create first relation GridViewRelation carsRelation = new GridViewRelation(this.radGridView1.MasterTemplate); carsRelation.ChildTemplate = carTemplate; carsRelation.RelationName = "ParentChild"; carsRelation.ParentColumnNames.Add("ID2"); carsRelation.ChildColumnNames.Add("ID"); this.radGridView1.Relations.Add(carsRelation); this.radGridView1.MasterTemplate.Templates.Add(carTemplate); this.radGridView1.MasterTemplate.Templates[0].AllowAddNewRow = false; this.radGridView1.MasterTemplate.Templates[0].Columns["ID"].IsVisible = false; this.radGridView1.MasterTemplate.Templates[0].Columns["ID2"].IsVisible = false; this.radGridView1.MasterTemplate.Templates[0].Columns["Model"].Width = 150; this.radGridView1.MasterTemplate.Templates[0].Columns["Model"].ReadOnly = true; this.radGridView1.MasterTemplate.Templates[0].Columns["Qty"].Width = 150; this.radGridView1.MasterTemplate.Templates[0].Columns["Price"].Width = 150; this.radGridView1.AutoGenerateColumns = false; this.radGridView1.AutoSizeRows = true; this.radGridView1.ReadOnly = true; this.radGridView1.AutoGenerateHierarchy = false; this.radGridView1.EnableCustomFiltering = true; this.radGridView1.EnableFiltering = true; this.radGridView1.ShowFilteringRow = false; } private void radGridView1_CustomFiltering(object sender, GridViewCustomFilteringEventArgs e) { if (string.IsNullOrEmpty(this.radTextBox1.Text)) { e.Visible = true; for (int i = 0; i < this.radGridView1.ColumnCount; i++) { e.Row.Cells[i].Style.Reset(); e.Row.InvalidateRow(); } foreach (GridViewRowInfo row in e.Row.ChildRows) { for (int i = 0; i < this.radGridView1.Templates[0].ColumnCount; i++) { row.Cells[i].Style.Reset(); row.InvalidateRow(); } } return; } e.Visible = false; // looking through each column of the parent row for (int i = 0; i < this.radGridView1.ColumnCount; i++) { string text = e.Row.Cells[i].Value.ToString(); if (text.IndexOf(this.radTextBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) { e.Visible = true; e.Row.Cells[i].Style.CustomizeFill = true; e.Row.Cells[i].Style.DrawFill = true; e.Row.Cells[i].Style.BackColor = Color.FromArgb(201, 252, 254); } else { e.Row.Cells[i].Style.Reset(); e.Row.InvalidateRow(); } } foreach (GridViewRowInfo row in e.Row.ChildRows) { for (int i = 0; i < this.radGridView1.Templates[0].ColumnCount; i++) { string text = row.Cells[i].Value.ToString(); if (text.IndexOf(this.radTextBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) { e.Visible = true; e.Row.IsExpanded = true; row.Cells[i].Style.CustomizeFill = true; row.Cells[i].Style.DrawFill = true; row.Cells[i].Style.BackColor = Color.FromArgb(201, 252, 254); } else { row.Cells[i].Style.Reset(); row.InvalidateRow(); } } } } private void radTextBox1_TextChanged(object sender, EventArgs e) { this.radGridView1.MasterTemplate.Refresh(); } } public class Person { public int ID { get; set; } public int ID2 { get; set; } public string Name { get; set; } public decimal Price { get; set; } public decimal Qty { get; set; } public Person(){ } public Person(int id, int id2, string name, decimal price, decimal qty) { ID = id; ID2 = id2; Name = name; Price = price; Qty = qty; } } public class Car { public int ID { get; set; } public int ID2 { get; set; } public string Model { get; set; } public int Qty { get; set; } public decimal Price { get; set; } public Car() { } public Car(int id, int id2, string model, decimal price, int qty) { ID = id; ID2 = id2; Model = model; Qty = qty; Price = price; } } }Hope that helps
Richard
Hello Richard
Thank you very much.
it works.
but there is a problem with that. it only searches the rows from first child template(by default) or the active (visible) child template.
I want to search a specific child template.
at first I was about to find a way to set the active child template programmatically (Posted here) but I couldn't.
Is there another way to search only ONE specific child template.
thanks in advance.
You can adapt the sample I gave to either look at both the parent and child rows, or just the parent or just the child rows. Likewise, if you have more than a second level then you will need to adapt it again to search the child rows of the child rows.
So, to search just the second level, you just need to comment out a bit of code
// looking through each column of the parent row //for (int i = 0; i < this.radGridView1.ColumnCount; i++) //{ // string text = e.Row.Cells[i].Value.ToString(); // if (text.IndexOf(this.radTextBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) // { // e.Visible = true; // e.Row.Cells[i].Style.CustomizeFill = true; // e.Row.Cells[i].Style.DrawFill = true; // e.Row.Cells[i].Style.BackColor = Color.FromArgb(201, 252, 254); // } // else // { // e.Row.Cells[i].Style.Reset(); // e.Row.InvalidateRow(); // } //} foreach (GridViewRowInfo row in e.Row.ChildRows) { for (int i = 0; i < this.radGridView1.Templates[0].ColumnCount; i++) { string text = row.Cells[i].Value.ToString(); if (text.IndexOf(this.radTextBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase) >= 0) { e.Visible = true; e.Row.IsExpanded = true; row.Cells[i].Style.CustomizeFill = true; row.Cells[i].Style.DrawFill = true; row.Cells[i].Style.BackColor = Color.FromArgb(201, 252, 254); } else { row.Cells[i].Style.Reset(); row.InvalidateRow(); } } }Regards,
Richard
Hello Richard
thank you for reply
As I said the code works fine. Let me explain my purpose a little more.
I have a master Gridview And FIVE child templates. I want to search the child rows BUT I want to Choose ONE of these child templates in run-time to search. I mean the User can choose which Child template must be searched.(third child template for instance) but not by expanding the rows and select that child template. I have a dropdownlist to choose which child template must be searched.
This code only searches the first child template and I could not access and search the other child templates.
I hope You Understand what I mean.
regards
Yes, I understand. You can certainly adapt it to search the child templates, but the issue that you will lhave is as per this other thread of yours . As far as I know you will not be able to select the tab that you need to show that you have found the right result.
Regards,
Richard
Regards,
Jack
the Telerik team
int currentRow = radGridView1.CurrentRow.Index;
this.radGridView1.Rows[currentRow + 1].IsCurrent = true;
Thank you for writing.
The RadGridView.CurrentRow property indicates which row is current. You can set it to a row from any template in the grid.
I hope this information helps. Should you have further questions I would be glad to help.
Regards,
Dess
Progress Telerik
