C# - 在页面更改时在gridview中维护复选框和文本框的状态

时间:2018-01-11 09:50:42

标签: c# asp.net gridview checkbox webforms

我有一个带有文本框和复选框的gridview。当选中该复选框时,将在文本框中填入一个值,用户可以更改该值。

以下是gridview的代码

<asp:GridView ID="gvPayment" runat ="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="Vertical" Width="100%" ShowFooter="true" CssClass="jumbSize1" OnRowDataBound="gvPayment_RowDataBound" AllowPaging="true" PageSize="5" OnPageIndexChanging="gvPayment_PageIndexChanging" >
<Columns>
    <asp:TemplateField HeaderStyle-Width="5%">
        <ItemTemplate>
            <asp:CheckBox ID="chkSelect" runat="server" CssClass="checkbox" OnCheckedChanged="chkSelect_CheckedChanged" AutoPostBack="true" />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="TRANSACTION DATE" HeaderStyle-Width="15%">
        <ItemTemplate>
            <asp:Label ID="SalesDate" runat="server" Text='<%#Eval("Date", "{0:dd/MM/yyyy}") %>' />
        </ItemTemplate>
        <FooterTemplate>
            <asp:Button ID="Submit" Text="Submit" runat="server" OnClick="Submit_Click" CssClass="btn btn-primary" />
        </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Sales Code" HeaderStyle-Width="15%">
        <ItemTemplate>
            <asp:Label ID="SalesCode" runat="server" Text='<%#Eval("SALES_CODE") %>' />
        </ItemTemplate>
         <FooterTemplate>
        <div style="padding: 0 0 5px 0;">
            <asp:Label Text="Page Totals" runat="server" align="right" />
        </div>
         <div>
            <asp:Label Text="Grand Totals" runat="server" align="right" />
        </div>
    </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="ACTUAL SALE" HeaderStyle-Width="15%">
        <ItemTemplate>
            <asp:Label ID="ActualSales" runat="server" Text='<%#Eval("ACTUAL", "{0:N2}") %>' />
        </ItemTemplate>
         <FooterTemplate>
        <div style="padding: 0 0 5px 0;">
            <asp:Label ID="PageActual" runat="server" align="right" />
        </div>
         <div>
            <asp:Label ID="GrandActual" runat="server" align="right" />
        </div>
    </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="ADVANCE" HeaderStyle-Width="15%">
        <ItemTemplate>
            <asp:Label ID="AdvPay" runat="server" Text='<%#Eval("ADVANCE", "{0:N2}") %>' />
        </ItemTemplate>
         <FooterTemplate>
        <div style="padding: 0 0 5px 0;">
            <asp:Label ID="PageAdvance" runat="server" align="left" />
        </div>
         <div>
            <asp:Label ID="GrandAdvance" runat="server" align="left" />
        </div>
    </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="AMOUNT DUE" HeaderStyle-Width="15%">
        <ItemTemplate>
            <asp:Label ID="AmtDue" runat="server" Text='<%#Eval("DUE", "{0:N2}") %>' />
        </ItemTemplate>
         <FooterTemplate>
        <div style="padding: 0 0 5px 0;">
            <asp:Label ID="PageDue" runat="server" align="left" />
        </div>
         <div>
            <asp:Label ID="GrandDue" runat="server" align="left" />
        </div>
    </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="AMOUNT PAID" HeaderStyle-Width="15%">
        <ItemTemplate>
            <asp:TextBox ID="AmtPaid" runat="server" CssClass="form-control CapLock" />
        </ItemTemplate>
    </asp:TemplateField>
</Columns>
<AlternatingRowStyle BackColor="#4870BE" ForeColor="#FFFFFF" />
<FooterStyle BackColor="#76543c" ForeColor="#FFFFFF" Font-Bold="true" />
<HeaderStyle BackColor="#76543c" ForeColor="#FFFFFF" Font-Bold="true" />
<PagerSettings Mode="NextPrevious" NextPageText="Next &amp;gt;&amp;gt;" PreviousPageText="Prev &amp;lt;&amp;lt;" />
<PagerStyle BackColor="#76543c" ForeColor="#FFFFFF" HorizontalAlign="Center" />
<RowStyle BackColor="#EFF3FB" /></asp:Gridview>

以下是将gridview绑定到数据源并在viewstate中获取总计的代码

private void GetCustomer()
{
    dt = new DataTable();
    try
    {
        using (con = new SqlConnection(conString))
        {
            using (cmd = con.CreateCommand())
            {
                string query = @"dbo.sp_get_sales";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = query;
                cmd.Parameters.AddWithValue("@ID", CustInfo.SelectedValue);
                con.Open();

                da = new SqlDataAdapter();
                da.SelectCommand = cmd;
                da.Fill(dt);

                //CALCULATE THE TOTAL AMOUNTS AND HOLD THE VALUE IN A "VIEWSTATE"
                ViewState["TotalActual"] = null;
                if (ViewState["TotalActual"] == null)
                {
                    Decimal dActual = 0;
                    for (int i = 0; i <= dt.Rows.Count - 1; i++)
                    {
                        dActual += dt.Rows[i].Field<Decimal>("ACTUAL");
                    }
                    ViewState["TotalActual"] = dActual.ToString("N2");
                }

                ViewState["TotalAdvance"] = null;
                if (ViewState["TotalAdvance"] == null)
                {
                    Decimal dAdvance = 0;
                    for (int i = 0; i <= dt.Rows.Count - 1; i++)
                    {
                        dAdvance += dt.Rows[i].Field<Decimal>("ADVANCE");
                    }
                    ViewState["TotalAdvance"] = dAdvance.ToString("N2");
                }

                ViewState["TotalDue"] = null;
                if (ViewState["TotalDue"] == null)
                {
                    Decimal dDue = 0;
                    for (int i = 0; i <= dt.Rows.Count - 1; i++)
                    {
                        dDue += dt.Rows[i].Field<Decimal>("DUE");
                    }
                    ViewState["TotalDue"] = dDue.ToString("N2");
                }
            }
            //BIND QUERY RESULT WITH THE GRIDVIEW
            gvPayment.DataSource = dt;
            gvPayment.DataBind();
        }
    }
    catch (Exception ex)
    {
        ErrorMessage.Text = "An error occured: " + ex.Message;
    }
    finally
    {
        con.Close();
        con.Dispose();
    }

    foreach (GridViewRow row in gvPayment.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            TextBox AmtPaid = (TextBox)row.FindControl("AmtPaid");
            AmtPaid.Attributes.Add("readonly", "readonly");
        }
    }
}

以下是在检查已更改事件

上启用和填充文本框的代码
protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
    GridViewRow row = ((GridViewRow)((CheckBox)sender).NamingContainer);
    int index = row.RowIndex;
    CheckBox chkSelect = (CheckBox)gvPayment.Rows[index].FindControl("chkSelect");
    TextBox AmtPaid = (TextBox)gvPayment.Rows[index].FindControl("AmtPaid");
    Label AmtDue = (Label)gvPayment.Rows[index].FindControl("AmtDue");

    if (chkSelect.Checked && chkSelect != null)
    {
        AmtPaid.Text = AmtDue.Text.Replace(",", "");
        AmtPaid.Attributes.Remove("readonly");
    }
    else
    {
        AmtPaid.Text = string.Empty;
        AmtPaid.Attributes.Add("readonly", "readonly");
    }
}

当选中该复选框但两个控件都在pageindexchanging事件上丢失了值时,文本框会填充所需的值。

我希望复选框保持其状态和文本框,以维护用户在调用pageindexchanging事件时输入的值。

以下是移至下一页的代码

protected void gvPayment_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gvPayment.PageIndex = e.NewPageIndex;
    GetCustomer();
}

注意:我已经完成了所有建议的类似问题而没有运气或成功。

1 个答案:

答案 0 :(得分:0)

您必须坚持使用它们,例如将Disctionary<int, bool>存储在密钥为ViewState的{​​{1}}中,且值为RowIndex({{1}是bool?):

CheckBox

我会将此逻辑封装在一个方法中,您需要从Checkedprotected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ViewState["EnabledAmtPaidTextBoxes"] = new Dictionary<int, bool>(); GetCustomer(); } } 调用它。您不再需要RowDataBound中的最后一个循环:

CheckedChanged

此外,如果您使用using语句,则GetCustomer中不需要protected void gvPayment_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { EnabledAmtPaidTextBox(e.Row); } } protected void chkSelect_CheckedChanged(object sender, EventArgs e) { CheckBox chkSelect = (CheckBox)sender; GridViewRow row = (GridViewRow)chkSelect.NamingContainer; EnabledAmtPaidTextBox(row, chkSelect.Checked); } private void EnabledAmtPaidTextBox(GridViewRow row, bool? newCheckedOrApplyOld = null) { TextBox AmtPaid = (TextBox)row.FindControl("AmtPaid"); Label AmtDue = (Label)row.FindControl("AmtDue"); CheckBox chkSelect = (CheckBox)row.FindControl("chkSelect"); Dictionary<int, bool> enabledAmtPaidTextBoxes = (Dictionary<int, bool>)ViewState["EnabledAmtPaidTextBoxes"]; if (!enabledAmtPaidTextBoxes.ContainsKey(row.RowIndex)) enabledAmtPaidTextBoxes[row.RowIndex] = false; if (newCheckedOrApplyOld.HasValue) enabledAmtPaidTextBoxes[row.RowIndex] = newCheckedOrApplyOld.Value; else chkSelect.Checked = enabledAmtPaidTextBoxes[row.RowIndex]; if (enabledAmtPaidTextBoxes[row.RowIndex]) { AmtPaid.Text = AmtDue.Text.Replace(",", ""); AmtPaid.Attributes.Remove("readonly"); } else { AmtPaid.Text = string.Empty; AmtPaid.Attributes.Add("readonly", "readonly"); } } con.Close,因为这已由con.Dispose - 语句完成