Search code examples
c#asp.netwebformstelerikradgrid

RadGrid Refreshes on Detail Table Expansion


I needed to create a grid with multiple groups on certain columns my code for it is

<telerik:RadGrid Skin="MetroTouch" ID="grdQuestionnaire" RenderMode="Lightweight" runat="server"
                        AllowMultiRowSelection="True" AllowPaging="True" ShowGroupPanel="False"
                        AutoGenerateColumns="False" GridLines="none"
                        showchooser="true"
                        OnItemCommand="grdQuestionnaire_ItemCommand"
                      
                        OnNeedDataSource="grdQuestionnaire_NeedDataSource"
                        OnItemDataBound="grdQuestionnaire_ItemDataBound"
                        OnDetailTableDataBind="grdQuestionnaire_DetailTableDataBind">
                        <GroupingSettings ShowUnGroupButton="false"></GroupingSettings>
                        <MasterTableView GroupLoadMode="Client" NoMasterRecordsText="No Question Added" TableLayout="Fixed" DataKeyNames="QuestionId,QuestionCode,LanguageQ">
                            <DetailTables >
                                <telerik:GridTableView  NoDetailRecordsText="No Options Added" Name="Options" Width="100%">
                                    <Columns>
                                        <telerik:GridBoundColumn SortExpression="OptionDesc" HeaderText="Option" HeaderButtonType="TextButton"
                                            DataField="OptionDesc">
                                        </telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn SortExpression="OptionWeightage" HeaderText="Weightage" HeaderButtonType="TextButton"
                                            DataField="OptionWeightage">
                                        </telerik:GridBoundColumn>
                                    </Columns>
                                </telerik:GridTableView>
                            </DetailTables>
                            <GroupByExpressions>
                                <telerik:GridGroupByExpression>
                                    <SelectFields>
                                        <telerik:GridGroupByField FieldAlias="WorkshopName" FieldName="WorkshopName" HeaderText="Workshop"></telerik:GridGroupByField>
                                    </SelectFields>
                                    <GroupByFields>
                                        <telerik:GridGroupByField FieldName="WorkshopCode"></telerik:GridGroupByField>
                                    </GroupByFields>
                                </telerik:GridGroupByExpression>

                                <telerik:GridGroupByExpression>
                                    <SelectFields>

                                        <telerik:GridGroupByField FieldAlias="" FieldName="AssessmentType" HeaderText="Type"></telerik:GridGroupByField>
                                        <telerik:GridGroupByField FieldAlias="QuestionnaireDesc" FieldName="QuestionnaireDesc" HeaderText="Description" FormatString=""></telerik:GridGroupByField>
                                    </SelectFields>
                                    <GroupByFields>

                                        <telerik:GridGroupByField FieldName="QuestionnaireCode"></telerik:GridGroupByField>
                                    </GroupByFields>
                                </telerik:GridGroupByExpression>

                                <telerik:GridGroupByExpression>
                                    
                                    <SelectFields>
                                        <telerik:GridGroupByField FieldAlias="QuestionCode" FieldName="QuestionCode" HeaderText="Question">                                               
                                        </telerik:GridGroupByField>
                                        
                                    </SelectFields>
                                    <GroupByFields>
                                        <telerik:GridGroupByField FieldName="QuestionCode"></telerik:GridGroupByField>
                                    </GroupByFields>
                                </telerik:GridGroupByExpression>

                            </GroupByExpressions>
                            <Columns>
                                <telerik:GridBoundColumn DataField="QuestionDesc" HeaderText="Question"></telerik:GridBoundColumn>
                                <telerik:GridBoundColumn DataField="QuestionWeightage" HeaderText="Weightage"></telerik:GridBoundColumn>
                                <telerik:GridBoundColumn DataField="LanguageQ" HeaderText="Language"></telerik:GridBoundColumn>
                                <telerik:GridBoundColumn DataField="CreatedBy" HeaderText="Created By"></telerik:GridBoundColumn>
                                <telerik:GridTemplateColumn HeaderText="Action" UniqueName="colAction">
                                    <HeaderStyle HorizontalAlign="Left" Font-Bold="false" VerticalAlign="NotSet" />
                                    <ItemTemplate>
                                        <asp:LinkButton ID="addOption" CommandName="addNewOption" runat="server" CssClass="btn btn-info">Add Options</asp:LinkButton>
                                        <asp:LinkButton ID="deleteQuestion" CommandName="deletequestion" runat="server" CssClass="btn btn-danger">Delete</asp:LinkButton>
                                       
                                    </ItemTemplate>

                                    <HeaderStyle Font-Bold="True" />
                                </telerik:GridTemplateColumn>
                            </Columns>

                        </MasterTableView>
                    </telerik:RadGrid>
  1. I have a scenario where I need to show buttons with groups - this part is done by subscribing the event OnItemDataBound

        protected void grdQuestionnaire_ItemDataBound(object sender, GridItemEventArgs e)
    {
        if (e.Item is GridGroupHeaderItem)
        {
    
            GridGroupHeaderItem hi = (GridGroupHeaderItem)e.Item;
            DataRowView groupDataRow = (DataRowView)e.Item.DataItem;
            DataRowView drv = ((DataRowView)e.Item.DataItem);
            string columnname = drv.DataView.Table.Columns[0].ColumnName;
    
            switch (columnname)
            {
                case "WorkshopName":
                    {
                        LinkButton btn = new LinkButton();
    
                        btn.Text = "Add workshop";
                        // btn.OnClientClick = "if (!confirm('Are you sure you all information is correct for this employee?')) return false;";
                        btn.CssClass = "btn btn-sm btn-info";
                        btn.Style.Add(HtmlTextWriterStyle.MarginRight, "0px");
                        btn.CommandName = "AddWorkshop";
                        TableCell customcell = new TableCell();
                        customcell.Controls.Add(btn);
                        hi.Cells.Add(customcell);
                        hi.Cells[hi.Cells.Count - 2].ColumnSpan = hi.Cells[hi.Cells.Count - 2].ColumnSpan - 1;
                        break;
                    }
                case "QuestionCode":
                    {
                        LinkButton btn = new LinkButton();
                        btn.Text = "Add question";
                        btn.CssClass = "btn btn-sm btn-success";
                        btn.Style.Add(HtmlTextWriterStyle.MarginRight, "0px");
                        btn.CommandName = "AddQuestion";
                        TableCell customcell = new TableCell();
                        customcell.Controls.Add(btn);
                        hi.Cells.Add(customcell);
                        hi.Cells[hi.Cells.Count - 2].ColumnSpan = hi.Cells[hi.Cells.Count - 2].ColumnSpan - 1;
                        break;
                    }
            }
        }
    }
    

The output for this code is as follows enter image description here

  1. On expansion the table comes from other datatable which I am adding from following event OnDetailTableDataBind

        protected void grdQuestionnaire_DetailTableDataBind(object sender, Telerik.Web.UI.GridDetailTableDataBindEventArgs e)
    {
        GridDataItem dataItem = (GridDataItem)e.DetailTableView.ParentItem;
        string n = e.DetailTableView.Name;
        string QuestionCode = dataItem.GetDataKeyValue("QuestionCode").ToString();
        string Language = dataItem.GetDataKeyValue("LanguageQ").ToString();
        DataSet ds = clsQuestionnaireDAC.GetOptions(QuestionCode, Language);
        e.DetailTableView.DataSource = ds.Tables[0];
    }
    

I don't know why the problem occurs when the table is expanded my custom buttons mysteriously vanish and rests the grid. here is the result after expanding the detail table enter image description here Any one can guide me through this situation to prevent my MasterTableView as is before expansion.


Solution

  • Generally, it is a better idea to use templates in similar scenarios: http://docs.telerik.com/devtools/aspnet-ajax/controls/grid/functionality/grouping/group-header-and-footer-templates

    For example, if you have the following definition:

                   <GroupByExpressions>
                        <telerik:GridGroupByExpression>
                            <GroupByFields>
                                <telerik:GridGroupByField FieldName="ShipCountry" />
                            </GroupByFields>
                            <SelectFields>
                                <telerik:GridGroupByField FieldName="ShipCountry" />
                            </SelectFields>
                        </telerik:GridGroupByExpression>
                        <telerik:GridGroupByExpression>
                            <GroupByFields>
                                <telerik:GridGroupByField FieldName="ShipName" />
                            </GroupByFields>
                            <SelectFields>
                                <telerik:GridGroupByField FieldName="ShipName" />
                            </SelectFields>
                        </telerik:GridGroupByExpression>
                    </GroupByExpressions>

    You can use something similar to this:

                    <GroupHeaderTemplate>
                        <asp:Label runat="server" ID="ShipCountryLabel" Text='<%# "ShipCountry: "+
                        (((GridGroupHeaderItem)Container).AggregatesValues["ShipCountry"]) %>'
                            Visible='<%# ((((GridGroupHeaderItem)Container).AggregatesValues["ShipCountry"]) != null) %>'>
                        </asp:Label>
                        <asp:Label runat="server" ID="ShipNameLabel" Text='<%# "ShipName: "+
                        (((GridGroupHeaderItem)Container).AggregatesValues["ShipName"]) %>'
                            Visible='<%# ((((GridGroupHeaderItem)Container).AggregatesValues["ShipName"]) != null) %>'>
                        </asp:Label>
                        <br />
                        <asp:Button ID="Button2" runat="server" Text="MyButton"
                            Visible='<%# ((((GridGroupHeaderItem)Container).AggregatesValues["ShipName"]) != null) %>' />
                    </GroupHeaderTemplate>

    This will display the button only for the inner group level.

    If you insist on using a code-behind approach, you will need to use ItemCreated. You can use the approach demonstrated below to extract the field name and add the control in a later stage of the page life cycle:

        protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e)
    {
        if (e.Item is GridGroupHeaderItem)
        {
            GridGroupHeaderItem headerItem = e.Item as GridGroupHeaderItem;
            int index = headerItem.GroupIndex.Split('_').Length - 1;
            GridGroupByExpression exp = headerItem.OwnerTableView.GroupByExpressions[index] as GridGroupByExpression;
            string fieldName = exp.GroupByFields[0].FieldName;
    
            if (fieldName == "ShipName")
            {
                Button button = new Button()
                {
                    ID = "GroupButton1",
                    Text = "MyButton"
                };
    
                headerItem.Load += (s, a) =>
                {
                    headerItem.DataCell.Controls.Add(new Literal() { Text = headerItem.DataCell.Text });
                    headerItem.DataCell.Controls.Add(button);
                };
            }
        }
    }
    

    I hope this will prove helpful.