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

Detail view does render correctly with self-referencing hierarchy

1 Answer 118 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Elton Pei
Top achievements
Rank 1
Elton Pei asked on 09 Apr 2010, 01:18 AM

Hi,

I am using the self-referencing hierarchy and dynamically assigning datasource (via dataset). I followed the demo code to implement my grid. Depending the value of a dropdownlist on the page, the datasource for the radgrid is different so I set AutoGenerateColumns="True". The problem that I'm having is that when a different value is selected from the dropdown, the mastertableview binds fine and the new columns are rendered but the detail views in the grid still retains the columns from a previous binding which results in the detail views having blank rows and mis-aligned with the parent table.

Any help is greatly appreciated.

Here's my aspx definition,

<telerik:RadGrid  
                                                                            ID="grdVwDashBoard"   
                                                                            runat="server"   
                                                                            AutoGenerateColumns="True" 
                                                                            onitemdatabound="grdVwDashBoard_ItemDataBound"   
                                                                                OnColumnCreated="grdVwDashBoard_ColumnCreated"   
                                                                                OnItemCreated="grdVwDashBoard_ItemCreated" Width="750px" Skin="Vista"   
                                                                                EnableLinqExpressions="false" > 
                                                                                <ClientSettings AllowExpandCollapse="True">  
                                                                                    <Scrolling UseStaticHeaders="true" AllowScroll="true" FrozenColumnsCount="0" SaveScrollPosition="true" /> 
                                                                                </ClientSettings> 
                                                                                <MasterTableView HeaderStyle-CssClass="gridHeaders" EnableNoRecordsTemplate="true" CommandItemDisplay="None" ItemStyle-CssClass="gridrowstyle" ShowHeadersWhenNoRecords="false" HierarchyDefaultExpanded="false" HierarchyLoadMode="Client" DataKeyNames="MetricID, ParentMetricID, metricname" FilterExpression="ParentMetricID is NULL" Width="100%">   
                                      <NoRecordsTemplate> 
                                      <span class="emptyDataStyle">Please select a dashboard from the menu above.</span>              
                                      </NoRecordsTemplate>     
                                      <SelfHierarchySettings MaximumDepth="5" KeyName="MetricID" ParentKeyName="ParentMetricID" /> 
                                      <CommandItemSettings ShowExportToCsvButton="true" ShowAddNewRecordButton="false" ShowRefreshButton="false" ExportToCsvImageUrl="images/xlsx.gif" ExportToCsvText="Export to Excel" /> 
                                      <HeaderStyle CssClass="gridHeaders" Wrap="false" /> 
                                      <ItemStyle CssClass="gridrowstyle" /> 
                                                                                </MasterTableView> 
                                                                                <ExportSettings ExportOnlyData="true" OpenInNewWindow="true"></ExportSettings> 
                                                                            </telerik:RadGrid> 
 

 

 

 

And here's the code,
 

 

 protected void grdVwDashBoard_ItemDataBound(object sender, GridItemEventArgs e)  
        {  
            if (e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem)  
            {  
                // loop through all measures and find out if the measure is integer type  
                // if interger type then format the value  
                int totalMeasuresCount = (int)Session["totalMeasuresCount"];  
 
                try 
                {  
                    for (int i = 0; i < e.Item.Cells.Count; i++)  
                    {  
                        int cellNo = 2;  
                        cellNo = i + cellNo;  
 
                        int num;  
                        bool measureVal = int.TryParse(e.Item.Cells[cellNo].Text.ToString(), out num);  
 
                        if (measureVal == true)  
                        {  
                            e.Item.Cells[cellNo].Text = int.Parse(e.Item.Cells[cellNo].Text).ToString("n0");  
                        }  
                    }  
 
                }  
                catch 
                {  
                }  
            }  
 
            CreateExpandCollapseButton(e.Item, "metricname");  
        }  
 
        public void Page_PreRenderComplete(object sender, EventArgs e)  
        {  
            HideExpandColumnRecursive(grdVwDashBoard.MasterTableView);  
            //HideExpandColumnRecursive(grid.MasterTableView);  
        }  
 
        private void HideExpandColumnRecursive(GridTableView tableView)  
        {  
            GridItem[] nestedViewItems = tableView.GetItems(GridItemType.NestedView);  
            foreach (GridNestedViewItem nestedViewItem in nestedViewItems)  
            {  
                foreach (GridTableView nestedView in nestedViewItem.NestedTableViews)  
                {  
                    nestedView.Style["border"] = "0";  
 
                    Button MyExpandCollapseButton = (Button)nestedView.ParentItem.FindControl("MyExpandCollapseButton");  
 
                    if (nestedView.Items.Count == 0)  
                    {  
                        if (MyExpandCollapseButton != null)  
                        {  
                            MyExpandCollapseButton.Style["visibility"] = "hidden";  
                        }  
 
                        nestedViewItem.Visible = false;  
                    }  
                    else 
                    {  
                        if (MyExpandCollapseButton != null)  
                        {  
                            MyExpandCollapseButton.Style.Remove("visibility");  
                        }  
                    }  
 
                    if (nestedView.HasDetailTables)  
                    {  
                        HideExpandColumnRecursive(nestedView);  
                    }  
                }  
            }  
        }  
 
        protected void grdVwDashBoard_ColumnCreated(object sender, GridColumnCreatedEventArgs e)  
        {  
            //e.OwnerTableView.CommandItemDisplay = GridCommandItemDisplay.None;  
 
            if (e.Column is GridExpandColumn)  
            {  
                e.Column.Visible = false;  
            }  
            else if (e.Column is GridBoundColumn)  
            {  
                GridBoundColumn column = e.Column as GridBoundColumn;  
                if (NO_DISPLAY_FIELDS.Any(a => a == column.DataField))  
                {  
                    e.Column.Visible = false;  
                }  
                else if (column.DataField == "metricname")  
                {  
                    e.Column.HeaderText = "Metric Name";  
                    e.Column.HeaderStyle.Width = Unit.Pixel(200);  
                }  
                else 
                {  
                    e.Column.HeaderStyle.Width = Unit.Pixel(100);  
                }  
            }  
        }  
 
        protected void grdVwDashBoard_ItemCreated(object sender, GridItemEventArgs e)  
        {  
            CreateExpandCollapseButton(e.Item, "metricname");  
 
            if (e.Item is GridHeaderItem && e.Item.OwnerTableView != grdVwDashBoard.MasterTableView)  
            {  
                //e.Item.Visible = false;  
                e.Item.Style["display"] = "none";  
            }  
 
            if (e.Item is GridNestedViewItem)  
            {  
                e.Item.Cells[0].Visible = false;  
            }  
        }  
 
        public void CreateExpandCollapseButton(GridItem item, string columnUniqueName)  
        {  
            if (item is GridDataItem)  
            {  
                if (item.FindControl("MyExpandCollapseButton") == null)  
                {  
                    Button button = new Button();  
                    button.Click += new EventHandler(button_Click);  
                    button.CommandName = "ExpandCollapse";  
                    button.CssClass = (item.Expanded) ? "rgCollapse" : "rgExpand";  
                    button.ID = "MyExpandCollapseButton";  
 
                    if (item.OwnerTableView.HierarchyLoadMode == GridChildLoadMode.Client)  
                    {  
                        string script = String.Format(@"$find(""{0}"")._toggleExpand(this, event); return false;", item.Parent.Parent.ClientID);  
 
                        button.OnClientClick = script;  
                    }  
 
                    int level = item.ItemIndexHierarchical.Split(':').Length;  
                    if (level > 1)  
                    {  
                        button.Style["margin-left"] = level + 10 + "px";  
                    }  
 
                    TableCell cell = ((GridDataItem)item)[columnUniqueName];  
                    cell.Controls.Add(button);  
                    cell.Controls.Add(new LiteralControl("&nbsp;"));  
                    cell.Controls.Add(new LiteralControl(((GridDataItem)item).GetDataKeyValue(columnUniqueName).ToString()));  
                }  
            }  
        }  
 
        void button_Click(object sender, EventArgs e)  
        {  
            ((Button)sender).CssClass = (((Button)sender).CssClass == "rgExpand") ? "rgCollapse" : "rgExpand";  
        } 

 

1 Answer, 1 is accepted

Sort by
0
Veli
Telerik team
answered on 14 Apr 2010, 12:13 PM
Hi Elton,

As discussed in your support ticket thread, RadGrid does not support auto-generated columns with self-referencing hierarchy when the data source changes on postback. Let me repeat the core points from it, so that our community can benefit from our conversation. To implement this scenario, there is a set of strict requirements you need to follow:

1. No auto-generated grid columns, otherwise RadGrid gets messed up try to persist and  recreate grid column then the data changes.

2. User-defined grid columns need to be recreated on every postback, so that no ViewState is maintained for them.

The combination of these 2 rules implies that you have to create RadGrid programmatically in Page_Init (Section "Creating grid entirely on code-behind")

For reference, I have created a simplified implementation of this scenario. RadGrid is entirely created in the code-behind, with all its columns recreated in Page_Init on every postback. Try the example, and note that when changing data sources, apart from the 2 columns that are identical (and define the hierarchy), there is a third different column for each data source. Under normal cases, these 2 columns would get messed up. But once I start defining my column dynamically on every postback, the grid now does not manage any of the columns and I get my structure OK.

Finally, what might be challenging for your scenario is creating columns dynamically on Page_Init before databinding happens. This implies  that you need to know which data set RadGrid will be bound to at 2 points: once in Page_Init to create the respective columns, and once in NeedDataSource to bind the grid.


Regards,
Veli
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Tags
Grid
Asked by
Elton Pei
Top achievements
Rank 1
Answers by
Veli
Telerik team
Share this question
or