Search code examples
asp.netgridviewwebformspostbackrowdatabound

Why does Gridview lose BackColor on button click


I have a gridview that has certain rows set to a BackColor based on a value from one of the columns.

ASPX

<asp:GridView ID="uxTktGridView" runat="server" ShowHeaderWhenEmpty="true" CssClass="GridView" BorderStyle="Solid" onRowDataBound="uxTktGridView_RowDataBound" AutoGenerateColumns="False" OnSorting="uxTktGridView_Sorting" BackColor="White" BorderColor="#D6D2D2" BorderWidth="1px" CellPadding="3" SelectedIndex="-1" DataKeyNames="Ticket Number" AllowSorting="True"  Font-Size="Small" Width="100%" Visible="True" EnableModelValidation="True" style=" margin-top: 10px; margin-bottom: 10px;" OnSelectedIndexChanged="uxTktGridView_SelectedIndexChanged1" EnableViewState="true">
  <Columns>
    <asp:CommandField ShowSelectButton="True" SelectText="Details" ButtonType="Button" HeaderText="Select" />
    <asp:BoundField DataField="Ticket Number" HeaderText="Ticket Number" SortExpression="Ticket Number" />
    <asp:BoundField DataField="Date Of Request" HeaderText="Date Of Request" SortExpression="Date Of Request" />
    <asp:BoundField DataField="Requestor Name" HeaderText="Requestor Name" SortExpression="Requestor Name" />
    <asp:BoundField DataField="Requestor State" HeaderText="Requestor State" SortExpression="Requestor State" />
    <asp:BoundField DataField="Complexity" HeaderText="Complexity" SortExpression="Complexity" />
    <asp:BoundField DataField="Nature of Inquiry" HeaderText="Nature of Inquiry" SortExpression="Nature of Inquiry" />
    <asp:BoundField DataField="Staff" HeaderText="Staff" SortExpression="Staff" />
    <asp:BoundField DataField="Ticket Status" HeaderText="Ticket Status" SortExpression="Ticket Status" />
    <asp:BoundField DataField="Ticket Closure Date" HeaderText="Ticket Closure Date" SortExpression="Ticket Closure Date" />
  </Columns> 
  <FooterStyle BackColor="White" ForeColor="#000066" />
  <HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
  <PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
  <RowStyle ForeColor="#000066" />
  <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
  <SortedAscendingCellStyle BackColor="#F1F1F1" />
  <SortedAscendingHeaderStyle BackColor="#007DBB" />
  <SortedDescendingCellStyle BackColor="#CAC9C9" />
  <SortedDescendingHeaderStyle BackColor="#00547E" />
</asp:GridView>

To set the BackColor, I am using the _RowDataBound function on the backend:

C#

protected void uxTktGridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        DataRowView drv = (DataRowView)e.Row.DataItem;
        DateTime currentDate = DateTime.UtcNow.Date;
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            if (drv != null)
            {
                for (int i = 1; i < uxTktGridView.Columns.Count; i++) //index starts with 1 because the first column in the "select" button.
                {
                    if (e.Row.Cells[8].Text.Equals("OPEN"))
                    {
                        string tier = e.Row.Cells[5].Text.ToString();
                        string date = e.Row.Cells[2].Text.ToString();
                        DateTime recordDate = Convert.ToDateTime(date, CultureInfo.InvariantCulture);
                        int measureDate = (currentDate.Date - recordDate.Date).Days;
                        if (tier == "1")
                        {
                            if (measureDate >= 20)
                            {
                                e.Row.BackColor = Color.FromName("#E56E94");
                            }
                        }
                        else if (tier == "2")
                        {
                            if (measureDate >= 30)
                            {
                                e.Row.BackColor = Color.FromName("#E56E94");
                            }
                        }
                        else if (tier == "3")
                        {
                            if (measureDate >= 35)
                            {
                                e.Row.BackColor = Color.FromName("#E56E94");
                            }
                        }
                        else if (tier == "4")
                        {
                            if (measureDate >= 40)
                            {
                                e.Row.BackColor = Color.FromName("#E56E94");
                            }
                        }  
                    }
                     ...
                }
            }
        }
    }

I have 2 problems with the same issue. If I 1) Click a button or 2) Click one of the rows - the grid whites out and does not apply the BackColor settings. I am guessing that this is some PostBack related issue. I have tried adding AutoPostBack="false" to the buttons as well as to the grid. The behavior still occurs. I have also tried adding 'EnableViewState="false"(based on a suggestion) to thegridview. When I click a button, this basically makes mygridview` disappear. Any recommendations on how to resolve this issue?


Solution

  • Understanding the order of events in WebForms can be most helpful with this sort of thing. For the sake of example, Page and Control can be interchanged with the event names. The order of events are as follows:

    1. Page_Init(...) (no ViewState data is available)
    2. Page_Load(...) (ViewState is available)
    3. Control events (e.g. Click, RowSelect, et cetera)
    4. PreRender (...)

    If you are not databinding the grid after the postback (it is best to call DataBind() in PreRender after all of your page logic has completed) and do not have EnableViewState set to true, then you will lose this information posted in the grid and will be unable to access it in the postback. The ViewState is assigned between Init and Load and allows you to access properties of the controls. If you're calling DataBind() in Page_Load, then your control events may yield unpredictable results as the underlying data may differ.

    In other words, if you want to use the GridView as you have it defined, EnableViewState, at least for the GridView, needs to be true. Then, you should not DataBind it again during the postback

    void Page_PreRender(object sender, EventArgs e)
    {
        if (!Page.IsPostback)
        {
            DataBind();
        }
    }
    

    and the state should effectively be preserved. Also, don't change the value of your AutoPostBack property.