RadGrid hierarchy collapses on grid rebind.

8 posts, 0 answers
  1. Steve Holdorf
    Steve Holdorf avatar
    119 posts
    Member since:
    Apr 2010

    Posted 20 Jul 2012 Link to this post

    I am using AjAX RAD CONTROLS 2012. I have a radgrid setup with a master/details hierarchy and everything works well. Also note that in the details row I have a details table with a button. When the button is presses it fires the OnItemCommand. The only problem is that when The OnItemCommand event command fires with the master/details hierarchy opened and in the OnItemCommand event a call to the grid’s rebind method the hierarchy collapses. What is the best way to keep the master/details stay opened on a rebind?

    Thanks for all of your help.


    Steve Holdorf
  2. Shinu
    Shinu avatar
    17764 posts
    Member since:
    Mar 2007

    Posted 23 Jul 2012 Link to this post

    Hi Steve Holdorf,

    Please take a look into the following code snippet to retain expanded/selected state in hierarchy on rebind.

    ASPX:
    <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        <AjaxSettings>
            <telerik:AjaxSetting AjaxControlID="RadGrid1">
                <UpdatedControls>
                    <telerik:AjaxUpdatedControl ControlID="RadGrid1" LoadingPanelID="RadAjaxLoadingPanel1" />
                </UpdatedControls>
            </telerik:AjaxSetting>
        </AjaxSettings>
    </telerik:RadAjaxManager>
    <asp:Button ID="grdRebind" runat="server" Text="Rebind grid" OnClick="grdRebind_Click" />
    <telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" />
    <telerik:RadGrid ID="RadGrid1" DataSourceID="SqlDataSource1" runat="server"
         AutoGenerateColumns="False" AllowSorting="True" AllowMultiRowSelection="true"
         OnDataBound="RadGrid1_DataBound" OnItemCommand="RadGrid1_ItemCommand">
        <MasterTableView DataSourceID="SqlDataSource1" DataKeyNames="CustomerID" CommandItemDisplay="Top">
            <DetailTables>
                <telerik:GridTableView DataKeyNames="OrderID" DataSourceID="SqlDataSource2"
                    runat="server" CommandItemDisplay="Top">
                    <ParentTableRelation>
                        <telerik:GridRelationFields DetailKeyField="CustomerID" MasterKeyField="CustomerID" />
                    </ParentTableRelation>
                    <Columns>
                        <telerik:GridBoundColumn SortExpression="OrderID" HeaderText="OrderID" HeaderButtonType="TextButton"
                            DataField="OrderID" UniqueName="OrderID">
                        </telerik:GridBoundColumn>
                        <telerik:GridBoundColumn SortExpression="EmployeeID" HeaderText="EmployeeID" HeaderButtonType="TextButton"
                            DataField="EmployeeID" UniqueName="EmployeeID">
                        </telerik:GridBoundColumn>
                        <telerik:GridButtonColumn UniqueName="OrdersSelectColumn" CommandName="Select" Text="Select" />
                        <telerik:GridButtonColumn UniqueName="OrdersDeselectColumn" CommandName="Deselect"
                            Text="Deselect" />
                    </Columns>
                </telerik:GridTableView>
            </DetailTables>
            <Columns>
                <telerik:GridBoundColumn SortExpression="CustomerID" HeaderText="CustomerID" HeaderButtonType="TextButton"
                    DataField="CustomerID" UniqueName="CustomerID">
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn SortExpression="ContactName" HeaderText="Contact Name" HeaderButtonType="TextButton"
                    DataField="ContactName" UniqueName="ContactName">
                </telerik:GridBoundColumn>
                <telerik:GridButtonColumn UniqueName="CustomersSelectColumn" CommandName="Select"
                    Text="Select" />
                <telerik:GridButtonColumn UniqueName="CustomersSelectColumn" CommandName="Deselect"
                    Text="Deselect" />
            </Columns>
        </MasterTableView>
    </telerik:RadGrid>

    C#:
    private Hashtable _ordersExpandedState;
    private Hashtable _selectedState;
      
    public void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //reset states
            this._ordersExpandedState = null;
            this.Session["_ordersExpandedState"] = null;
            this._selectedState = null;
            this.Session["_selectedState"] = null;
        }
    }
    //Save/load expanded states Hash from the session
    //this can also be implemented in the ViewState
    private Hashtable ExpandedStates
    {
        get
        {
            if (this._ordersExpandedState == null)
            {
                _ordersExpandedState = this.Session["_ordersExpandedState"] as Hashtable;
                if (_ordersExpandedState == null)
                {
                    _ordersExpandedState = new Hashtable();
                    this.Session["_ordersExpandedState"] = _ordersExpandedState;
                }
            }
      
            return this._ordersExpandedState;
        }
    }
      
    //Clear the state for all expanded children if a parent item is collapsed
    private void ClearExpandedChildren(string parentHierarchicalIndex)
    {
        string[] indexes = new string[this.ExpandedStates.Keys.Count];
        this.ExpandedStates.Keys.CopyTo(indexes, 0);
        foreach (string index in indexes)
        {
            //all indexes of child items
            if (index.StartsWith(parentHierarchicalIndex + "_") ||
                index.StartsWith(parentHierarchicalIndex + ":"))
            {
                this.ExpandedStates.Remove(index);
            }
        }
    }
      
    private void ClearSelectedChildren(string parentHierarchicalIndex)
    {
        string[] indexes = new string[this.SelectedStates.Keys.Count];
        this.SelectedStates.Keys.CopyTo(indexes, 0);
        foreach (string index in indexes)
        {
            //all indexes of child items
            if (index.StartsWith(parentHierarchicalIndex + "_") ||
                index.StartsWith(parentHierarchicalIndex + ":"))
            {
                this.SelectedStates.Remove(index);
            }
        }
    }
      
    //Save/load selected states Hash from the session
    //this can also be implemented in the ViewState
    private Hashtable SelectedStates
    {
        get
        {
            if (this._selectedState == null)
            {
                _selectedState = this.Session["_selectedState"] as Hashtable;
                if (_selectedState == null)
                {
                    _selectedState = new Hashtable();
                    this.Session["_selectedState"] = _selectedState;
                }
            }
      
            return this._selectedState;
        }
    }
    protected void RadGrid1_ItemCommand(object source, GridCommandEventArgs e)
    {
        //save the expanded/selected state in the session
        if (e.CommandName == RadGrid.ExpandCollapseCommandName)
        {
            //Is the item about to be expanded or collapsed
            if (!e.Item.Expanded)
            {
                //Save its unique index among all the items in the hierarchy
                this.ExpandedStates[e.Item.ItemIndexHierarchical] = true;
            }
            else //collapsed
            {
                this.ExpandedStates.Remove(e.Item.ItemIndexHierarchical);
                this.ClearSelectedChildren(e.Item.ItemIndexHierarchical);
                this.ClearExpandedChildren(e.Item.ItemIndexHierarchical);
            }
        }
        //Is the item about to be selected
        else if (e.CommandName == RadGrid.SelectCommandName)
        {
            //Save its unique index among all the items in the hierarchy
            this.SelectedStates[e.Item.ItemIndexHierarchical] = true;
        }
        //Is the item about to be deselected
        else if (e.CommandName == RadGrid.DeselectCommandName)
        {
            this.SelectedStates.Remove(e.Item.ItemIndexHierarchical);
        }
    }
    protected void RadGrid1_DataBound(object sender, EventArgs e)
    {
        //Expand all items using our custom storage
        string[] indexes = new string[this.ExpandedStates.Keys.Count];
        this.ExpandedStates.Keys.CopyTo(indexes, 0);
      
        ArrayList arr = new ArrayList(indexes);
        //Sort so we can guarantee that a parent item is expanded before any of
        //its children
        arr.Sort();
      
        foreach (string key in arr)
        {
            bool value = (bool)this.ExpandedStates[key];
            if (value)
            {
                RadGrid1.Items[key].Expanded = true;
            }
        }
      
        //Select all items using our custom storage
        indexes = new string[this.SelectedStates.Keys.Count];
        this.SelectedStates.Keys.CopyTo(indexes, 0);
      
        arr = new ArrayList(indexes);
        //Sort to ensure that a parent item is selected before any of its children
        arr.Sort();
      
        foreach (string key in arr)
        {
            bool value = (bool)this.SelectedStates[key];
            if (value)
            {
                RadGrid1.Items[key].Selected = true;
            }
        }
    }

    Please check this code library for more details.

    Thanks,
    Shinu.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Steve Holdorf
    Steve Holdorf avatar
    119 posts
    Member since:
    Apr 2010

    Posted 24 Jul 2012 Link to this post

    Your code worked great!

    Thanks,


    Steve Holdorf
  5. Tim Black
    Tim Black avatar
    9 posts
    Member since:
    Nov 2002

    Posted 22 Jan 2013 Link to this post

    I just came across this solution and wanted to thank you.  It worked great!!
  6. Kiko
    Kiko avatar
    1 posts
    Member since:
    Sep 2014

    Posted 24 Sep 2014 Link to this post

    I tried this on my first attempt to use parent and child grid, and it worked perfectly. thank you for support systems like this. thank you.
  7. Shraddha
    Shraddha avatar
    1 posts
    Member since:
    Oct 2013

    Posted 23 Dec 2014 Link to this post

    this is really great piece of code works well . Thankyou
  8. Eyup
    Admin
    Eyup avatar
    3012 posts

    Posted 26 Dec 2014 Link to this post

    Hello Shraddha,

    Recently, a new property was introduced to achieve this implementation:
    <MasterTableView ... RetainExpandStateOnRebind="true">

    Hope this helps.

    Regards,
    Eyup
    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.

     
  9. Abhishek
    Abhishek avatar
    1 posts
    Member since:
    Aug 2015

    Posted 08 Oct 2015 in reply to Eyup Link to this post

    Thank you Shraddha.... it worked just fine for 3-level grid too..
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017