Master grid not rebinding after detail table delete command

7 posts, 0 answers
  1. Marty
    Marty avatar
    22 posts
    Member since:
    Feb 2008

    Posted 28 Dec 2010 Link to this post

    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();  
                }
            }
  2. Princy
    Princy avatar
    17421 posts
    Member since:
    Mar 2007

    Posted 29 Dec 2010 Link to this post

    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.
  3. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2289 posts

    Posted 30 Dec 2010 Link to this post

    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.
  4. Marty
    Marty avatar
    22 posts
    Member since:
    Feb 2008

    Posted 30 Dec 2010 Link to this post

    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;
                }
            }
  5. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2289 posts

    Posted 05 Jan 2011 Link to this post

    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.
  6. Raymond
    Raymond avatar
    26 posts
    Member since:
    Jul 2014

    Posted 18 Jan Link to this post

    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
  7. Eyup
    Admin
    Eyup avatar
    3420 posts

    Posted 23 Jan Link to this post

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