OnDemand Hierarchical DataGrid

11 posts, 1 answers
  1. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 01 Oct 2019 Link to this post

    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

  2. Jesse
    Jesse avatar
    10 posts
    Member since:
    Aug 2018

    Posted 02 Oct 2019 Link to this post

    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

  3. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3898 posts

    Posted 02 Oct 2019 Link to this post

    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.
  4. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 02 Oct 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    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

  5. Jesse
    Jesse avatar
    10 posts
    Member since:
    Aug 2018

    Posted 02 Oct 2019 in reply to Kashif Link to this post

    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.

  6. Jesse
    Jesse avatar
    10 posts
    Member since:
    Aug 2018

    Posted 02 Oct 2019 in reply to Jesse Link to this post

    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;

     

  7. Answer
    Jesse
    Jesse avatar
    10 posts
    Member since:
    Aug 2018

    Posted 02 Oct 2019 Link to this post

    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;
            }
        }
    }
  8. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 03 Oct 2019 in reply to Jesse Link to this post

    Thank a lot Jesse.

    By adding these 2 lines, GridView working now.

    ds.Relations.Add(dataRelation);

    childTemplate.HierarchyDataProvider = new GridViewEventDataProvider(childTemplate);

    Thank you again.

     

  9. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 03 Oct 2019 in reply to Jesse Link to this post

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

    Populating data without using DataSet Object.

    Thank you Jesse. You Make my day.

     

  10. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 04 Oct 2019 Link to this post

    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.

  11. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3898 posts

    Posted 04 Oct 2019 Link to this post

    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.
Back to Top