Hi Admins.
I have a requirement to Load/Populate Ondemand hierarchical DataGrid.(Detail grid should be shown on RowClick)
I have searched the forum but every example i found is building hierarchical gridview by using the DataSet.
But i want to do this by Using DataTable / Querying the Database.
How can i achieve the above stated requirement.
Please provide any example.
Thank you
10 Answers, 1 is accepted
Kashif,
The details regarding dynamic loading for child data is described at the link below. While the document has two references to a dataset, the binding is actually to a datatable. Once you load the initial data into the datasource of the datagrid object, you can leverage the RowSourceNeeded event to populate the child rows for the row being expanded. It also appears you need to populate the child template ahead of time. In the sample they provide, you would leverage the RowSourceNeeded to perform you query and load the data into the child template.
https://docs.telerik.com/devtools/winforms/controls/gridview/hierarchical-grid/load-on-demand-hierarchy
The help article that Jesse referred is the appropriate solution for loading on demand in RadGridView. You can also refer to our Demo application >> GridView >> Hierarchy >> Load on demand example which is quite useufl on this topic. The Demo application can be found in the installation folder of the suite which is usually located at the following path:
C:\Program Files (x86)\Progress\Telerik UI for WinForms R3 2019\Examples\QuickStart\Bin
@Jesse, I have also updated your Telerik points for community effort.
If you need any further assistance please don't hesitate to contact me.
Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik
I have setup grid view according to the information and my own logic, but i have some issues,
MasterTemplate populated, Child is not Populating.
What I'm doing is.
private
void
frmSaleListPending_Load(
object
sender, EventArgs e)
{
DataSet dataSet = CreateDataSet();
this
.MasterBindingSource.DataSource = dataSet;
this
.MasterBindingSource.DataMember =
"SALES_M"
;
this
.DetailBindingSource.DataSource = dataSet;
this
.DetailBindingSource.DataMember =
"SALES_D"
;
GridViewTemplate childTemplate = CreateChildTemplate();
this
.radGridView1.Templates.Add(childTemplate);
this
.radGridView1.DataSource =
this
.MasterBindingSource;
this
.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
this
.radGridView1.RowSourceNeeded +=
new
GridViewRowSourceNeededEventHandler(radGridView1_RowSourceNeeded);
}
private
DataSet CreateDataSet()
{
DataSet ds =
new
DataSet();
ds.Tables.Add(saleRepo.GetSaleDataQuery(
"Select * from Sales_m where status = 0"
));
ds.Tables[0].TableName =
"SALES_M"
;
ds.Tables.Add(saleRepo.GetSaleDataQuery(
"Select * from Sales_d"
));
ds.Tables[1].TableName =
"SALES_D"
;
DataRelation dataRelation;
dataRelation =
new
DataRelation(
"SALES_M_SALES_D"
,ds.Tables[
"SALES_M"
].Columns[
"SMID"
], ds.Tables[
"SALES_D"
].Columns[
"SMID"
]);
return
ds;
}
private
GridViewTemplate CreateChildTemplate()
{
GridViewTemplate template =
new
GridViewTemplate();
template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewTextBoxColumn Columnid =
new
GridViewTextBoxColumn
{
Name =
"smid"
,
HeaderText =
"smid"
,
FieldName =
"smid"
,
Width = 60,
IsVisible =
false
,
HeaderTextAlignment = ContentAlignment.MiddleCenter,
TextAlignment = ContentAlignment.MiddleCenter
};
GridViewTextBoxColumn ColumnSrNo =
new
GridViewTextBoxColumn
{
Name =
"sr_no"
,
HeaderText =
"Sr #"
,
FieldName =
"sr_no"
,
Width = 60,
HeaderTextAlignment = ContentAlignment.MiddleCenter,
TextAlignment = ContentAlignment.MiddleCenter
};
GridViewTextBoxColumn ColumnAlias =
new
GridViewTextBoxColumn
{
Name =
"Alias_Name"
,
HeaderText =
"Alias"
,
FieldName =
"Alias_name"
,
Width = 100,
HeaderTextAlignment = ContentAlignment.MiddleCenter,
TextAlignment = ContentAlignment.MiddleCenter
};
GridViewTextBoxColumn ColumnItemCode =
new
GridViewTextBoxColumn
{
Name =
"Item_Code"
,
HeaderText =
"Code"
,
FieldName =
"Item_Code"
,
Width = 100,
IsVisible =
false
,
HeaderTextAlignment = ContentAlignment.MiddleCenter,
TextAlignment = ContentAlignment.MiddleCenter
};
GridViewTextBoxColumn ColumnItemName =
new
GridViewTextBoxColumn
{
Name =
"Item_Name"
,
HeaderText =
"Item Description"
,
FieldName =
"Item_Name"
,
Width = 300,
HeaderTextAlignment = ContentAlignment.MiddleLeft,
TextAlignment = ContentAlignment.MiddleLeft
};
GridViewTextBoxColumn ColumnUOM =
new
GridViewTextBoxColumn
{
Name =
"ABBR"
,
HeaderText =
"M-Unit"
,
FieldName =
"ABBR"
,
Width = 50,
HeaderTextAlignment = ContentAlignment.MiddleLeft,
TextAlignment = ContentAlignment.MiddleLeft
};
GridViewDecimalColumn ColumnSaleRate =
new
GridViewDecimalColumn
{
Name =
"Sale_Rate"
,
HeaderText =
"Unit Price"
,
FieldName =
"Sale_Rate"
,
Width = 120,
FormatString =
"{0:N2}"
,
HeaderTextAlignment = ContentAlignment.MiddleRight,
TextAlignment = ContentAlignment.MiddleRight
};
GridViewDecimalColumn ColumnSaleQty =
new
GridViewDecimalColumn
{
Name =
"Qty"
,
HeaderText =
"Quantity"
,
FieldName =
"Qty"
,
Width = 120,
FormatString =
"{0:N2}"
,
HeaderTextAlignment = ContentAlignment.MiddleRight,
TextAlignment = ContentAlignment.MiddleRight
};
GridViewDecimalColumn ColumnItAmnt =
new
GridViewDecimalColumn
{
Name =
"itamnt"
,
HeaderText =
"Item Amnt"
,
FieldName =
"itamnt"
,
Width = 120,
FormatString =
"{0:N2}"
,
HeaderTextAlignment = ContentAlignment.MiddleRight,
TextAlignment = ContentAlignment.MiddleRight
};
GridViewDecimalColumn ColumnAmount =
new
GridViewDecimalColumn
{
Name =
"itfinalamnt"
,
HeaderText =
"Total Value"
,
FieldName =
"itfinalamnt"
,
Width = 120,
FormatString =
"{0:N2}"
,
HeaderTextAlignment = ContentAlignment.MiddleRight,
TextAlignment = ContentAlignment.MiddleRight
};
template.Columns.AddRange(Columnid,ColumnSrNo, ColumnAlias,
ColumnItemCode,
ColumnItemName,
ColumnUOM,
ColumnSaleRate,
ColumnSaleQty,
ColumnItAmnt,
ColumnAmount);
return
template;
}
private
void
radGridView1_RowSourceNeeded(
object
sender, GridViewRowSourceNeededEventArgs e)
{
DataRowView rowView = e.ParentRow.DataBoundItem
as
DataRowView;
DataRow[] rows = rowView.Row.GetChildRows(
"SALES_M_SALES_D"
);
//Relation Name
foreach
(DataRow dataRow
in
rows)
{
GridViewRowInfo row = e.Template.Rows.NewRow();
row.Cells[
"sr_no"
].Value = dataRow[
"sr_no"
];
row.Cells[
"Item_code"
].Value = dataRow[
"Item_code"
];
row.Cells[
"alias_Name"
].Value = dataRow[
"alias_Name"
];
row.Cells[
"Item_Name"
].Value = dataRow[
"Item_Name"
];
row.Cells[
"smid"
].Value = dataRow[
"smid"
];
row.Cells[
"Sale_Rate"
].Value = dataRow[
"sale_rate"
];
row.Cells[
"qty"
].Value = dataRow[
"qty"
];
row.Cells[
"itamnt"
].Value = dataRow[
"itamnt"
];
row.Cells[
"itfinalamnt"
].Value = dataRow[
"itfinalamnt"
];
e.SourceCollection.Add(row);
}
}
radGridView1_RowSourceNeeded is not called on clicking [+]
Please check what I'm doing wrong.
I have debug my code, both the tables with data are available in the dataset.
I think I'm Doing something wrong with creating relation between tables.
Thank You
Kashif,
Just from a quick glance, you are not adding the relationship to the dataset (ds.Relations.Add). You are also setting the fieldname on each child template column even though you are not binding a datasource to it, those should probably be removed.
Also, I thought you weren't using a dataset for this. You can leverage the data passed to the event to get the source row data. This wouldn't require you to configure the dataset or relationship stuff.
Kashif,
Additionally, you are also missed setting the HierarchyDataProvider. You should cast the ChildTemplate to a variable then set the HierarchyDataProvider and wire the event.
var _childTemplate = CreateChildTemplate();
exampleRadGridView.Templates.Add(_childTemplate);
_childTemplate.HierarchyDataProvider =
new
GridViewEventDataProvider(_childTemplate);
exampleRadGridView.RowSourceNeeded += ExampleRadGridView_RowSourceNeeded;
Here is a working example using only datatables and no dataset.
using
System;
using
System.Data;
using
Telerik.WinControls.UI;
namespace
example
{
public
partial
class
frmtest : Telerik.WinControls.UI.RadForm
{
private
DataTable _parentData =
new
DataTable();
public
frmtest()
{
InitializeComponent();
}
private
void
frmtest_Load(
object
sender, EventArgs e)
{
_parentData = exampleParentDataTableLoad();
// Replace with call to populate a datatable from a query
loadGridAndParentRecords();
}
private
void
loadGridAndParentRecords()
{
exampleRadGridView.DataSource = _parentData;
var _childTemplate = CreateChildTemplate();
exampleRadGridView.Templates.Add(_childTemplate);
_childTemplate.HierarchyDataProvider =
new
GridViewEventDataProvider(_childTemplate);
exampleRadGridView.RowSourceNeeded += ExampleRadGridView_RowSourceNeeded;
}
private
GridViewTemplate CreateChildTemplate()
{
GridViewTemplate template =
new
GridViewTemplate();
template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
template.Columns.Add(
new
GridViewTextBoxColumn
{
Name =
"Id"
,
HeaderText =
"ID"
});
template.Columns.Add(
new
GridViewTextBoxColumn
{
Name =
"SampleNumber"
,
HeaderText =
"Sample Number"
});
template.Columns.Add(
new
GridViewTextBoxColumn
{
Name =
"ParentId"
,
HeaderText =
"Parent Id"
});
return
template;
}
private
void
ExampleRadGridView_RowSourceNeeded(
object
sender, Telerik.WinControls.UI.GridViewRowSourceNeededEventArgs e)
{
if
(e.ParentRow !=
null
)
{
if
(e.ParentRow.DataBoundItem
is
DataRowView rowViewData)
{
var _childDataTable = exampleChildTableLoad();
// Replace with call to populate a datatable from a query
var _dataRows = _childDataTable.Select($
"ParentId = {rowViewData["
Id
"]}"
);
foreach
(DataRow row
in
_dataRows)
{
GridViewRowInfo _newRowObj = e.Template.Rows.NewRow();
_newRowObj.Cells[
"Id"
].Value = row[
"Id"
];
_newRowObj.Cells[
"SampleNumber"
].Value = row[
"SampleNumber"
];
_newRowObj.Cells[
"ParentId"
].Value = row[
"ParentId"
];
e.SourceCollection.Add(_newRowObj);
}
}
}
}
private
DataTable exampleParentDataTableLoad()
{
DataTable _return =
new
DataTable();
_return.Columns.Add(
"Id"
,
typeof
(
int
));
_return.Columns.Add(
"DisplayName"
,
typeof
(
string
));
_return.Rows.Add(1,
"Test1"
);
_return.Rows.Add(2,
"Test2"
);
return
_return;
}
private
DataTable exampleChildTableLoad()
{
DataTable _return =
new
DataTable();
_return.Columns.Add(
"Id"
,
typeof
(
int
));
_return.Columns.Add(
"SampleNumber"
,
typeof
(
string
));
_return.Columns.Add(
"ParentId"
,
typeof
(
int
));
_return.Rows.Add(9999,
"Test1"
, 2);
_return.Rows.Add(9998,
"Test2"
, 2);
_return.Rows.Add(9997,
"Test3"
, 2);
_return.Rows.Add(9996,
"Test4"
, 1);
_return.Rows.Add(9995,
"Test5"
, 1);
_return.Rows.Add(9994,
"Test6"
, 1);
return
_return;
}
}
}
Thank a lot Jesse.
By adding these 2 lines, GridView working now.
ds.Relations.Add(dataRelation);
childTemplate.HierarchyDataProvider = new GridViewEventDataProvider(childTemplate);
Thank you again.
Perfect solution. This what i require, exactly according to my requirement.
Populating data without using DataSet Object.
Thank you Jesse. You Make my day.
I have an other question.
I have to pass this Data (1 Master and linked detail not all the Data in the Grid) as parameter on double click Masterview row.
I can do this using single template gridview, But how to loop through only child rows of Clicked Master row.
Hello, Jesse,
Thank you for the community effort in this thread. I have rewarded you with Telerik points for this.
Hello, Kassif,
Note that each row from the parent level contains ChildRows collection which will give you access to the respective hierarchy rows on the second level. Thus, you can extract just the relevant child records for a certain parent.
I hope this information helps. If you need any further assistance please don't hesitate to contact me.
Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik