This is a migrated thread and some comments may be shown as answers.

OnDemand Hierarchical DataGrid

10 Answers 249 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Kashif
Top achievements
Rank 1
Kashif asked on 01 Oct 2019, 08:55 PM

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

Sort by
0
Jesse
Top achievements
Rank 1
answered on 02 Oct 2019, 12:15 PM

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

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 02 Oct 2019, 01:25 PM
Hello, Kashif,    

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

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Kashif
Top achievements
Rank 1
answered on 02 Oct 2019, 07:46 PM

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

0
Jesse
Top achievements
Rank 1
answered on 02 Oct 2019, 08:09 PM

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.

0
Jesse
Top achievements
Rank 1
answered on 02 Oct 2019, 08:28 PM

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;

 

0
Accepted
Jesse
Top achievements
Rank 1
answered on 02 Oct 2019, 08:35 PM

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;
        }
    }
}
0
Kashif
Top achievements
Rank 1
answered on 03 Oct 2019, 05:22 AM

Thank a lot Jesse.

By adding these 2 lines, GridView working now.

ds.Relations.Add(dataRelation);

childTemplate.HierarchyDataProvider = new GridViewEventDataProvider(childTemplate);

Thank you again.

 

0
Kashif
Top achievements
Rank 1
answered on 03 Oct 2019, 05:57 AM

Perfect solution. This what i require, exactly according to my requirement.

Populating data without using DataSet Object.

Thank you Jesse. You Make my day.

 

0
Kashif
Top achievements
Rank 1
answered on 04 Oct 2019, 06:13 AM

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.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 04 Oct 2019, 09:35 AM

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

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
GridView
Asked by
Kashif
Top achievements
Rank 1
Answers by
Jesse
Top achievements
Rank 1
Dess | Tech Support Engineer, Principal
Telerik team
Kashif
Top achievements
Rank 1
Share this question
or