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 exists
this
.GridView.Rows(0).ChildRows(1).IsSelected =
true
; // Knowing that it has at least 2 child rows
this
.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 cell
MessageBox.Show(
this
.GridView.Rows(0).ChildRows(1).Cells(2).ColumnInfo.HeaderText);
// Display the cell value
MessageBox.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