Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call RowDataBound from another function

I have a 2 Gridviews. The first grid has a button that when clicked it will populate a second grid with the data based on the id of the button clicked.

I then have code in the RowDataBound function to show the grid based on the row selected. But the problem is the code is automatically running the RowDataBound before the populate function. So the second grid isn't displaying.

Code for GridView:

<asp:GridView  style="width:75%"  
                        ID="gvCVRT" 
                        ShowHeaderWhenEmpty="true"
                        CssClass="tblResults" 
                        runat="server" 
                        OnRowDataBound="gvCVRT_RowDataBound"  
                        OnSelectedIndexChanged="gridviewParent_SelectedIndexChanged"                           
                        DataKeyField="ID" 
                        DataKeyNames="ChecklistID"
                        AutoGenerateColumns="false"
                        allowpaging="false"
                        AlternatingRowStyle-BackColor="#EEEEEE">
                        <HeaderStyle CssClass="tblResultsHeader" />
                        <Columns>
                            <asp:BoundField DataField="ChecklistID" HeaderText="ID"  ></asp:BoundField> 
                            <asp:CommandField ShowSelectButton="True" HeaderText="Select" />
                            <asp:BoundField DataField="ChecklistDate" HeaderText="Checklist Date" dataformatstring="{0:dd/MM/yyyy}"></asp:BoundField>
                            <asp:BoundField DataField="User" HeaderText="User" ></asp:BoundField>
                            <asp:BoundField DataField="Note" HeaderText="Note" ></asp:BoundField>

                        </Columns>
                    </asp:GridView> 

Code behind:

protected void gvCVRT_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        lookupCVRT work = (lookupCVRT)e.Row.DataItem;
        GridView gv = sender as GridView;

        if (work.ID != null)
        {
            int index = gv.Columns.HeaderIndex("Select");
            if (index > -1)
            {
                e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow");
                e.Row.Cells[index].ToolTip = "Click here to Edit Checklist";
            }
        }
    }
}

Code for select button:

protected void gridviewParent_SelectedIndexChanged(object sender, EventArgs e)
{
    List<lookupCVRT> workDetails = lookupCVRT.GetChecklistItemsByChecklistID(Company.Current.CompanyID, ParentID.ToString(), gvCVRT.SelectedDataKey.Value.ToString());
    gvCVRTDetails.DataSource = workDetails;
    gvCVRTDetails.DataBind();
    FireJavascriptCallback("setArgAndPostBack ();");
}

So the problem is when I click on the Select button in the grid it runs the RowDataBound first then the gridviewParent_SelectedIndexChanged but I need to run gridviewParent_SelectedIndexChanged first. Can I call the RowDataBound function from gridviewParent_SelectedIndexChanged?

Page_Load function:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            GetChecklistID = "";
            if (ParentID.HasValue)
            {
                ViewState["ParentID"] = ParentID;

                List<lookupCVRT> work = lookupCVRT.GetCVRTItems(Company.Current.CompanyID, ParentID.ToString());
                ViewState["CVRT"] = work;
                gvCVRT.DataSource = work;
                gvCVRT.DataBind();

            }
        }
        else
        {
            if (ViewState["ParentID"] != null)
            {
                ParentID = (int?)ViewState["ParentID"];
                List<lookupCVRT> work = ViewState["CVRT"] as List<lookupCVRT>;
                gvCVRT.DataSource = work;
                gvCVRT.DataBind();

            }
        }
    }
like image 688
user123456789 Avatar asked Feb 16 '16 14:02

user123456789


1 Answers

The OnRowDataBound event is only called if the DataBind method for the GridView has been called.

In your specific case, the problem is in Page_Load in the else branch of the Page.IsPostBack condition:

 else
{
    if (ViewState["ParentID"] != null)
    {
        ParentID = (int?)ViewState["ParentID"];
        List<lookupCVRT> work = ViewState["CVRT"] as List<lookupCVRT>;
        gvCVRT.DataSource = work;
        gvCVRT.DataBind();

    }
}

This code is run for each postback. Unless you reset ViewState["ParentID"] somewhere else in your code, on every postback you bind the GridView gvCVRT again. This is the reason that RowDataBound is called. After finishing Page_Load, the page calls the additional event handlers, in your case gridviewParent_SelectedIndexChanged.

In order to solve this problem, you need to change the code in your Page_Load handler so that there are no calls to DataBind for a postback:

// field moved to class level so that you can access this variable instead of a DataRow in gvCVRT
private List<lookupCVRT> work;

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        GetChecklistID = "";
        if (ParentID.HasValue)
        {
            ViewState["ParentID"] = ParentID;

            work = lookupCVRT.GetCVRTItems(Company.Current.CompanyID, ParentID.ToString());
            ViewState["CVRT"] = work;
            gvCVRT.DataSource = work;
            gvCVRT.DataBind();

        }
    }
    else
    {
        if (ViewState["ParentID"] != null)
        {
            ParentID = (int?)ViewState["ParentID"];
            work = ViewState["CVRT"] as List<lookupCVRT>;
        }
    }
}

The root cause of your problem is that you need the data in a postback request and that you put these into ViewState["CVRT"] instead of requesting the data anew. In web applications it is pretty common the read the data again for a new request. So you might think about whether you really need to put the data into ViewState or whether you can request them upon a postback from the data source.

Putting the data into ViewState increases the size of the page that is transferred to the client (basically you have the HTML for the GridView and in addition you have the data in ViewState). So requesting them anew would be the better way in most cases.

like image 52
Markus Avatar answered Oct 29 '22 17:10

Markus