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
