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

Hierarchical Grid - Hide Master Table row if no details

7 Answers 117 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Kyle
Top achievements
Rank 1
Kyle asked on 20 Nov 2014, 11:59 PM
Hi All,

I'm trying to find a way to correctly hide the master table row if there are now details.

protected void myGrid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
 {


        if (!e.IsFromDetailTable)
        {
         myGrid.DataSource = GetMasterData(Val1, Val2);  // filter by values
        }
 }


protected voidmyGrid_DetailTableDataBind(object source, Telerik.Web.UI.GridDetailTableDataBindEventArgs e)
{
        GridDataItem parentItem = e.DetailTableView.ParentItem as GridDataItem;
        if (parentItem.Edit)
        {
            return;
        }

        if (e.DetailTableView.Name == "ChildItems")
        {
            e.DetailTableView.DataSource = GetChildItems(int.Parse(parentItem.GetDataKeyValue("ID").ToString()), val1, val2, val3); // filter the rows off of other values
        }
}


Now my issue is that GetChildItems may return 0 rows if the filters don't return any matches.  I've tried looping over the data on a pre_render, but paging gets messed up because it's still part of the datasource.  I've seen that you have to remove it from the datasource, but how is that done if I only know if it should be removed after the detail is bound to it?


    protected void myGrid_PreRender(object sender, EventArgs e)
    {

       
        foreach (GridDataItem gdi in myGrid.MasterTableView.Items)
        {
            //LineCount is the count of child items that the parent actually has.
//so if the MasterData.ChildTable doesn't have items, but  it actually has lines in the DB, hide it.
            if (gdi.ChildItem.NestedTableViews[0].Items.Count == 0 && gdi["LineCount"].Text != "0")
            {
               //this messes up the paging.
                gdi.Display = false;
                gdi.ChildItem.Display = false;
            }
        }

Ideally I don't want to have to pass the child parameters into the GetMasterData() function.

Thanks in advanced.







7 Answers, 1 is accepted

Sort by
0
Angel Petrov
Telerik team
answered on 25 Nov 2014, 03:31 PM
Hi Kyle,

In order to remove the unneeded items from the data source you can follow one of two approaches.
  1. Delete the item inside the PreRender handler and rebind the grid.
    foreach (GridDataItem gdi in myGrid.MasterTableView.Items)
            {
     
                if (gdi.ChildItem.NestedTableViews[0].Items.Count == 0 && gdi["LineCount"].Text != "0")
                {
                   //Perform the delete
                   gdi.Rebind();
                }
            }
    Note that by deleting the item I mean removing it from the database/collection to which the grid is bound and that is returned by the GetMasterData method.
  2. Modify the GetMasterData logic in such a manner so it returns a collection of items that contain child records.


Regards,
Angel Petrov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Kyle
Top achievements
Rank 1
answered on 26 Nov 2014, 07:21 PM
Hi Angel,

If it's option 1:
        There is no rebind for the GridDataItem . . . should I be rebinding the grid or something else?

Thanks for the help!
0
Angel Petrov
Telerik team
answered on 01 Dec 2014, 12:00 PM
Hello Kyle,

Please accept my apologies for misleading you in my previous reply. Indeed you should call .Rebind() for the grid in order for it to properly recreate and repopulate. That said the correct logic should look something like this.

C#:
foreach (GridDataItem gdi in myGrid.MasterTableView.Items)
        {
  
            if (gdi.ChildItem.NestedTableViews[0].Items.Count == 0 && gdi["LineCount"].Text != "0")
            {
               //Perform the delete
               myGrid.Rebind();
            }
        }


Regards,
Angel Petrov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Kyle
Top achievements
Rank 1
answered on 01 Dec 2014, 11:09 PM
Hi Angel,

That still isn't working:
bool shouldRebind = true;
 
  protected void myGrid_PreRender(object sender, EventArgs e)
{
 List<DataRow> vics = new List<DataRow>();
        
        DataTable dt = (DataTable)myGrid.MasterTableView.DataSource;
        if (dt != null)
        {
            foreach (GridDataItem gdi in myGrid.MasterTableView.Items)
            {
                if (gdi.ChildItem.NestedTableViews[0].Items.Count == 0 && gdi["LineCount"].Text != "0")
                {
                    DataRow row = dt.Rows.OfType<DataRow>().Where(r => r["ReceiptID"].ToString() == gdi.GetDataKeyValue("ReceiptID").ToString()).Single();
                    vics.Add(row);
                }
 
 
            }
 
            
              foreach (DataRow r in vics)
                dt.Rows.Remove(r);
 
      
                Session["dt"] = dt;
                shouldRebind = false;
                myGrid.MasterTableView.DataSource = dt;
             
        }
 
        myGrid.Rebind();
}
 
 
 protected void myGrid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
    {
 
 
        if (!e.IsFromDetailTable && shouldRebind)
        {
            
            myGrid.DataSource = GetMasterData(Val1, Val2);
 
        }
        else
        {
            myGrid.DataSource = (DataTable)Session["dt"];
            shouldRebind = true;
        }
 
 
    }


0
Angel Petrov
Telerik team
answered on 04 Dec 2014, 01:30 PM
Hi Kyle,

Could you please ensure that the row is deleted properly from the DataTable?

Please modify the code as demonstrated below and test the page again.

C#:
protected void myGrid_PreRender(object sender, EventArgs e)
    {
        DataTable dt = (DataTable)myGrid.MasterTableView.DataSource;
        if (dt != null)
        {
            foreach (GridDataItem gdi in myGrid.MasterTableView.Items)
            {
                if (gdi.ChildItem.NestedTableViews[0].Items.Count == 0 && gdi["LineCount"].Text != "0")
                {
                    dt.Rows.OfType<DataRow>().Where(r => r["ReceiptID"].ToString() == gdi.GetDataKeyValue("ReceiptID").ToString()).First().Delete();
                }
            }
 
            Session["dt"] = dt;
            shouldRebind = false;         
        }
        myGrid.Rebind();
    }

If the above does not prove helpful I would kindly like to ask you to send us a small runnable sample that we can inspect.

Regards,
Angel Petrov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Kyle
Top achievements
Rank 1
answered on 04 Dec 2014, 10:00 PM
Hi Angel,

I can confirm that the rows are being removed.  I set a break point before and after the removal of the victims and the count decreased.
Do I need to remove the child (orphaned) rows from the detail table as well?

I also noticed that even though I was calling the rebind the master table wasn't calling needDataSource again.

Please advise.


0
Angel Petrov
Telerik team
answered on 09 Dec 2014, 12:26 PM
Hi Kyle,

In order to further investigate the problem we would need the page contents(markup and code-behind) so we could examine the exact implementation. Once we get a better understanding of the setup we will try to simulate the issue locally and find its root cause.

Regards,
Angel Petrov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
Grid
Asked by
Kyle
Top achievements
Rank 1
Answers by
Angel Petrov
Telerik team
Kyle
Top achievements
Rank 1
Share this question
or