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

Master grid not rebinding after detail table delete command

6 Answers 338 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Marty
Top achievements
Rank 1
Marty asked on 28 Dec 2010, 09:07 PM
Hi, I'm running into similar situation as other posts but not exactly the same.

I have a really simple case where I have a detail table that responds to a DeleteCommand, and all I want to do is rebind the parent.

The problem is, that inside the delete command handler, if I don't call rebind on anything and let the normal event mechanism work, the detail table will properly delete the row however the parent is not rebinded.  If I add a call to rebind the parent (see below - the last statement), then the rebind happens but both grids don't show the correct results on the screen. I don't think rebind can be called inside a delete command handler, just my hunch.

This should be really simple. I want to rebind the parent row when the detail changes.  What's the preferred approach?  I see a lot of ways people are discussing it - but want as little code as possible.

 protected void RadGrid1_ItemCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
        {
            RadGrid g = (RadGrid)source;
            GridEditableItem editedItem = e.Item as GridEditableItem;
            if (e.CommandName == RadGrid.DeleteCommandName)
            {
                var id = editedItem.GetDataKeyValue("UserRentItemId").ToString();
                _presenter.DeleteUserRentItem(int.Parse(id));
                e.Item.OwnerTableView.ParentItem.OwnerTableView.Rebind();  
            }
        }

6 Answers, 1 is accepted

Sort by
0
Princy
Top achievements
Rank 2
answered on 29 Dec 2010, 12:53 PM
Hello Marty,

Try the above code in DeleteCommand and check whether it works.

C#:
protected void RadGrid1_DeleteCommand(object sender, GridCommandEventArgs e)
   {
       if (e.Item.OwnerTableView.Name == "DetailTableName")//check with name if DetailTable
       {
           GridDataItem item = (GridDataItem)e.Item;
           var id = item.GetDataKeyValue("UserRentItemId").ToString();
           _presenter.DeleteUserRentItem(int.Parse(id));
           e.Item.OwnerTableView.ParentItem.OwnerTableView.Rebind();
       }
   }

Thanks,
Princy.
0
Nikolay Rusev
Telerik team
answered on 30 Dec 2010, 09:33 AM
Hello Marty,

RadGrid does not require to rebind it's master table when deleting item within detail table. The behavior that you are experiencing is quire expected.

Have in mind that DeteCommand is triggered before the command is handled by RadGrid, i.e deletion is performed and rebinding the grid within the handler will result in not executing the command.

Bellow article explains in great details how RadGrid functions:
http://www.telerik.com/help/aspnet-ajax/grdeventsequence.html

Regards,
Nikolay
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
0
Marty
Top achievements
Rank 1
answered on 30 Dec 2010, 05:32 PM
Hi Nikolay, let me just make sure I follow what you are saying because you say it is quite "expected" behavior.  Just to make sure I am not doing something that is preventing the behavior that I want.

Here's what I'm seeing and you can verify that this is the correct behavior.

When I handle the DeleteCommand for my Detail table, I find that the NeedDataSource Event does get called however the ARGS indicate that this is a detail binding.  And since my code (below) is sentisitve for that, I think I'm doing things correctly, i.e. even if I try to populate the datasouce on the master, it doesnt matter because the grid is rebinding its detail table only.    Snippet 1 confirms that I get called but its for detail only.

So what you are saying is that by design, the Master grid does not know about Detail changes, in this case an ItemCommand on the detail.  So what I did to fix this is Snippet 2.  I used a boolean to signal that I want the Master grid rebound, and this is checked after the Detail needs datasource is called.  See Snippet 2. 

My question then assuming that the behavior is again that the master will not rebind iteself if the detail changes:  is this a good approach in snippet 2 ?   I'm wondering if you thought of a way for us to invalidate a parent item easier in the future for cases like this.  I'm still confused about this - I'm surprised this is not something everyone needs all the time.  I need to enable/disable my parent item when there are no more detail records, etc.  Some people need to do things like update totals in the parent row.  I read a lot but don't see any definitive easy approach for this.

I'm purchasing these tools for my business and I want to take this opportunity to say that the tools and support by Telerik are unmatched in the industry!

Snippet 1 - typical needs datasource handler with master/detail relationships

   protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs args)
        {
            if (!args.IsFromDetailTable)
            {
                RentItemNeedDataSource(sender, args);
            }
        }

Snippet 2 - check to see if detailTableUpdated

protected void RadGrid1_DetailTableDataBind(object source, GridDetailTableDataBindEventArgs e)
        {
            RadGrid g = (RadGrid)source;
            GridDataItem dataItem = (GridDataItem)e.DetailTableView.ParentItem;
            switch (e.DetailTableView.Name)
            {
                case "Detail":
                    {
                        var id = dataItem.GetDataKeyValue("RentItemId").ToString();
                        UserRentItemNeedDataSource(e.DetailTableView, e);
                        if (detailTableUpdated)
                        {
                            detailTableUpdated = false;
                            g.Rebind();
                            return;
                        }
                        break;
                    }
                default:
                    break;
            }
        }
0
Nikolay Rusev
Telerik team
answered on 05 Jan 2011, 12:46 PM
Hello Marty,

I am not sure I fully understand your scenario, but yes you can use similar approach to force rebind of the grid within DetailDataBind. For your convenience I am attaching sample page.

Best wishes,
Nikolay
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
0
Raymond
Top achievements
Rank 1
answered on 18 Jan 2018, 06:34 PM

I have a similar situation where the parent grid lists error types and counts, while the child grid lists individual error records for the specified error type.  Below is my detail table databind event handler that is based on what Marty provided above.  Using Marty's logic, I found that the SQL call used to retrieve data for the child grid was being called twice.  In other words, it fetched the child data, then the grid rebind fetched the parent data, and that forced the child data to be retrieved a second time.  In the logic below, if the DetailTableUpdated flag is set, I don't bother calling executing the SQl to update the child table.

 

   

Protected Sub rgCategoryGrid_DetailTableDataBind(sender As Object, e As GridDetailTableDataBindEventArgs)
        Dim dataItem As GridDataItem = TryCast(e.DetailTableView.ParentItem, GridDataItem)
 
        If dataItem IsNot Nothing Then
            Select Case e.DetailTableView.Name
                Case "ErrorDetails"
                    If DetailTableUpdated Then
                        DetailTableUpdated = False
                        dtCllctnErrorTable = GetErrorCategoryTable()
                        rgCategoryGrid.Rebind()
                    Else
                        Dim ErrorTyp_ID As Integer
                        If Integer.TryParse(dataItem.GetDataKeyValue("ErrorTyp_ID").ToString(), ErrorTyp_ID) Then
                            e.DetailTableView.DataSource = GetErrorDetailTable(ErrorTyp_ID)
                        Else
                            e.DetailTableView.DataSource = Nothing
                        End If
                    End If
            End Select
 
        End If
End Sub
0
Eyup
Telerik team
answered on 23 Jan 2018, 02:34 PM
Hello Raymond,

It is not a good practice to include DataBind or Rebind within the DetailTableDataBind event handler. I want to clarify that you have 2 ways in this scenario:

1. If you don't want to update the master level - in this case you can just update the inner database and refresh the corresponding GridTableView using e.Item.OwnerTableView.Rebind() inside the OnDeleteCommand event handler of the grid.

2. If you want to update the master level - in this case you will need to make a query to update the inner database first, without rebinding the GridTableView instance. After that, you can call e.Item.OwnerTableView.OwnerGrid.Rebind() at the end of the OnDeleteCommand event handler. This will refresh the master and all detail GridTableViews automatically.

I hope this will prove helpful.

Regards,
Eyup
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Marty
Top achievements
Rank 1
Answers by
Princy
Top achievements
Rank 2
Nikolay Rusev
Telerik team
Marty
Top achievements
Rank 1
Raymond
Top achievements
Rank 1
Eyup
Telerik team
Share this question
or