【问题标题】:C#- Maintain State of Checkbox and textbox in gridview on page changingC#-在页面更改时保持gridview中的复选框和文本框的状态
【发布时间】:2023-03-20 07:45:01
【问题描述】:

我有一个 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");
    }
}

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

我希望复选框保持其状态,文本框保持用户在调用 pageindexchange 事件时输入的任何值。

这是跳转到下一页的代码

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

注意:我已经解决了所有建议的类似问题,但没有运气或成功。

【问题讨论】:

  • 我不明白会发生什么。你说他们在回发时失去了他们的价值,你在哪里检查他们是否失去了他们?在chkSelect_CheckedChanged 中,您正在修改AmtPaid.Text。什么时候改?你是只打电话给GetCustomer 还是一直打电话给if(!IsPostBack)
  • 我已经修改了我的问题。在页面加载时我使用 d if(!IsPostBack) 但在分页时我只使用 GetCustomer()
  • 你必须自己坚持。我会试着写一个答案。但请注意,这是一个错误:chkSelect.Checked &amp;&amp; chkSelect != null。如果它是 null 你会得到一个异常,因为你首先检查 chkSelect.Checked 。
  • 另外,如果你使用using-statement,你就不需要con.Closecon.Dispose
  • 如果您这样做,我将不胜感激。帮助我更正您在答案中发现的错误。

标签: c# asp.net gridview checkbox webforms


【解决方案1】:

您必须将它们持久化,例如通过将Disctionary&lt;int, bool&gt; 存储在ViewState 中,其中键是RowIndex,值是boolCheckBoxChecked?):

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ViewState["EnabledAmtPaidTextBoxes"] = new Dictionary<int, bool>();
        GetCustomer();
    }
}

我会将此逻辑封装在一个方法中,您需要从RowDataBoundCheckedChanged 调用它。您不再需要 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");
    }
}

此外,如果您使用 using 语句,则在 finally 中不需要 con.Closecon.Dispose,因为这是由 using 语句完成的。

【讨论】:

  • 谢谢蒂姆。让我应用你的答案并给你反馈。
  • 我试过这些代码。文本框的值保持不变,但复选框的选中状态未选中。其次,您的代码似乎没有注意到页面更改,因为如果选择了第一个页面的第一行,则所有其他后续页面的所有第一行都启用了其文本框的值。请指教。
  • @donsonde: 我有edited我的答案
  • 感谢@Tim 的耐心等待。你是最棒的。它就像魅力一样工作。我只对其进行了一项更改。在你有 row.RowIndex 的地方,我将其更改为 row.RowIndex + gvPayment.PageIndex * gvPayment。 PageSize 以适应每个页面中的唯一行。再次感谢您
  • 你好@Tim,很抱歉再次给你带来困扰。这仅在 AmtPaid 与 AmtDue 相同时有效。但是当您更改 AmtPaid 中的值并单击下一步然后单击上一个时,AmtPaid 中的值将更改为与 AmtDue 相同,而不是之前指定的不等于 AmtDue 的金额。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 2021-06-15
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多