简体   繁体   中英

OnCheckChanged Event of asp:CheckBox Not Firing When Unchecked From Within Nested GridView

I have conducted a lot of searches which included checkchanged or OncheckChanged keyword:

ASP.NET CheckBox does not fire CheckedChanged event when unchecking

https://forums.asp.net/t/1311576.aspx?Checkbox+not+firing+when+unchecking+using+OnCheckedChanged

OnCheckedChanged event not firing

OnCheckedChanged event handler of asp:checkbox does not fire when checkbox is unchecked

But this just doesn't seem to be working although I applied all suggestion from the links given above

I am tring to fire a CheckChanged Event From nested gridview, whose DataSource gets binded in parent grid's OnRowDataBound event.

My aspx markup

<asp:GridView ID="gvDocSchedule" runat="server" AutoGenerateColumns="false" CssClass="table table-striped color-black"
    OnRowDataBound="gvDocSchedule_RowDataBound" DataKeyNames="UserID">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <img alt="" style="cursor:pointer" src="UserPanel/images/Plus12.png" />                
                <asp:Panel ID="PanelSchedule" runat="server" Style="display:none">
                    <asp:GridView ID="gvScheduleDayNTime" runat="server" AutoGenerateColumns="false">
                        <Columns>
                            <asp:BoundField ItemStyle-Width="150px" DataField ="ScheduleDay" HeaderText="CheckInTime1"/>
                            <asp:BoundField ItemStyle-Width="150px" DataField ="CheckInTime1" HeaderText="CheckInTime1"/>
                            <asp:BoundField ItemStyle-Width="150px" DataField ="CheckOutTime1" HeaderText="CheckOutTime1"/>
                            <asp:BoundField ItemStyle-Width="150px" DataField ="CheckInTime2" HeaderText="CheckInTime2"/>
                            <asp:BoundField ItemStyle-Width="150px" DataField ="CheckOutTime2" HeaderText="CheckOutTime2"/>
                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:HiddenField ID="hdnForChkBox" runat="server" value="No" /> 

                                    <asp:CheckBox ID="CBoxAvailabilityTime1" ViewStateMode="Enabled" Checked="false" Enabled="true" EnableViewState="true" runat="server" Text="See Free TimeSlots For Booking In Time1" AutoPostBack="true"  OnCheckedChanged="CBoxAvailabilityTime1_CheckedChanged" />
                                    <br />
                                    <asp:CheckBox ID="CBoxAvailabilityTime2" runat="server" Text="See Free TimeSlots For Booking In Time1" AutoPostBack="true" OnCheckedChanged="CBoxAvailabilityTime2_CheckedChanged" />
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
                </asp:Panel>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField ControlStyle-Font-Bold="true" DataField="UserFirstName" HeaderText="Doctor's First Name" />
        <asp:BoundField DataField="UserLastName" HeaderText="Doctor's Last Name" />
        <asp:BoundField DataField="SpecializationName" HeaderText="Doctor's Specialization" />
        <asp:BoundField DataField="HospitalName" HeaderText="Hospital" />

    </Columns>
</asp:GridView>

I was trying it with CBoxAvailabilityTime1 CheckBox. As you guys can see ViewStateMode and EnableViewState has been taken care of not only in server tag but also in content page's tag, also these properties are true for master page

Parent Grid gets binded when user press a button and nested grid gets binded in parent's OnRowDataBound event

Here is My aspx.cs code

protected void CBoxAvailabilityTime1_CheckedChanged(object sender, EventArgs e)
{
    foreach (GridViewRow gvParentRow in gvDocSchedule.Rows)
        {
            if (gvParentRow.RowType == DataControlRowType.DataRow)
            {
                GridView gvDocSchedulesGetChildGrid = (GridView)gvParentRow.FindControl("gvScheduleDayNTime");
                if (gvDocSchedulesGetChildGrid != null)
                {
                    foreach (GridViewRow gvChildRow in gvDocSchedulesGetChildGrid.Rows)
                    {
                        CheckBox CBoxAvailabilityTime1 = (CheckBox)gvChildRow.FindControl("CBoxAvailabilityTime1");
                        CheckBox CBoxAvailabilityTime2 = (CheckBox)gvChildRow.FindControl("CBoxAvailabilityTime2");

                        if (((CheckBox)CBoxAvailabilityTime1).Checked)
                        {
                            CBoxAvailabilityTime2.Enabled = false;
                        }
                        if (!((CheckBox)CBoxAvailabilityTime1).Checked)
                        {
                            CBoxAvailabilityTime2.Enabled = true;
                        }
                   }
              }
          }
     }
}

With this setup CheckChanged Event Fires on Checking. On Checking it hits Page_ Load skips if(!IsPostBack) (as AutoPostBack=true ) and then control is directly transferred to CBoxAvailabilityTime1_CheckedChanged(object sender, EventArgs e) event handler function but on the other hand it doesn't fire on unchecking it postsbacks goes to Page load again Skips if(!IsPostBack) and does nothing instead of calling CBoxAvailabilityTime1_CheckedChanged(object sender, EventArgs e)

"Note:-" Page_Load is not involved. I can't bind parent grid in page_load, !IsPostBack because I dont need to bind it at first time when page gets loaded rather its binding happens inside a button click event, if a button is clicked only then parent grid must get binded.

Update 1:- This is how I bind data to parent grid

I am calling this function in a button click event

protected void BindDataToGridViewDocInArea()
    {
        using (SqlConnection con = new SqlConnection(constr))
        {
            con.Open();
            SqlCommand cmdFillGridDocInArea = new SqlCommand("some query with parameter here", con)
            cmdFillGridDocInArea.Parameters.AddWithValue("@AID", ddlAskArea.SelectedValue);
            SqlDataAdapter sdaFillGridDocInArea = new SqlDataAdapter(cmdFillGridDocInArea);
            DataTable dtFillGridDocInArea = new DataTable();
            sdaFillGridDocInArea.Fill(dtFillGridDocInArea);
            if (dtFillGridDocInArea.Rows.Count > 0)
            {
                gvDocSchedule.DataSource = dtFillGridDocInArea;
                gvDocSchedule.DataBind();
            }
            else
            {
                lblError.Text = string.Empty;
                lblError.Text = "No Record Exists Against Requst Specified";
            }
            con.Dispose();
         }
    }

Tested a stripped down version of you snippet. It seems to be working. When you check CBoxAvailabilityTime1 , it disables CBoxAvailabilityTime2 . When you uncheck CBoxAvailabilityTime1 the other one is enabled again.

However this is only when the DataBinding of gvDocSchedule is inside an IsPostBack check. When it's not the checkboxes will always go to their default unchecked state after PostBack.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        //this works
        gvDocSchedule.DataSource = LoadFromDB();
        gvDocSchedule.DataBind();
    }

    //this does not
    gvDocSchedule.DataSource = LoadFromDB();
    gvDocSchedule.DataBind();
}

Or in your case something like this:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        BindDataToGridViewDocInArea();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM