RadGrid Refreshes on Detail Table Expansion
Asked Answered
E

2

10

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.

Enantiomorph answered 17/6, 2016 at 10:42 Comment(1)
Have you tried to use RadAjaxPanel ? Because each time you expand master view the page posts back causing your columns to reset.Swing
S
3

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.

Stendhal answered 24/6, 2016 at 13:37 Comment(0)
F
3

Try using the ItemCreated event.

I suspect the following is happening:

  1. ItemDataBound fires, your buttons are created

  2. There is a postback to bind the detail table

  3. The parent rows are not rebound at this moment, so ItemDataBound does not fire, so the dynamically created controls are not recreated, so they disappear

Farant answered 21/6, 2016 at 14:13 Comment(3)
I need data like columnname ` DataRowView drv = ((DataRowView)e.Item.DataItem); string collumname = drv.DataView.Table.Columns[0].ColumnName;` but it is retrieved as null when ItemCreated event is passedEnantiomorph
yup, you don't have the data yet at this point. COnsider showing a dialog with details instead of using detail tables: demos.telerik.com/aspnet-ajax/controls/examples/integration/…Farant
i want to bring notice on a technique I am using here , I am identifying column names to check which groupItem is being created and on that basis I am adding buttons. so I need the DataRowView alsoEnantiomorph
S
3

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.

Stendhal answered 24/6, 2016 at 13:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.