使用复选框在 gridview 中提交多行 (C#)

Submitting multiple rows in gridview with Checkboxes (C#)

我的目标是获取数据:

到目前为止,我能够使用存储过程将 sql 数据显示到 gridvew,我还能够使用复选框将数据发送到本地 table。

问题:
尽管选中了多个复选框,但只有一行数据被提交到 table。

例如。我单击了 3 个复选框,想要将 3 行不同的数据添加到 table。我点击提交按钮,当我检查 table 时,只有一个“检查”行被提交给 table 3 次。

已编辑代码:

protected void btnSubmit_Click(object sender, EventArgs e)
    {
        string connectionString = ConfigurationManager.ConnectionStrings["localDataB"].ConnectionString;

        using (var sqlConnection = new SqlConnection(connectionString))
        {
            sqlConnection.Open();

            string insertStatement = "INSERT into LocalDB (Item1, Item2, Item3)" + "(@Item1, @Item2, @Item3)";

            string Data1, Data2;
            float Data3;

            foreach (GridViewRow gRow in GridView1.Rows)
            {

                CheckBox ckSel = (gRow.FindControl("checker") as CheckBox);
                if (ckSel.Checked)
                {
                    Data1 = Convert.ToString(gRow.Cells[1].Text);
                    Data2 = Convert.ToString(gRow.Cells[2].Text);
                    Data3 = Convert.ToInt32(gRow.Cells[3].Text);

                    using (var sqlCommand = new SqlCommand(insertStatement, sqlConnection))
                    {
                        sqlCommand.Parameters.Add("Item1", SqlDbType.Text).Value = Data1;
                        sqlCommand.Parameters.Add("Item2", SqlDbType.Text).Value = Data2;
                        sqlCommand.Parameters.Add("Item3", SqlDbType.Float).Value = Data3;
                        sqlCommand.ExecuteNonQuery();
                    }
                }
            }
        }
        GVbind();

网格内复选框的代码:

<asp:GridView ID="GridView1" runat="server" EmptyDataText="No Data Found" BackColor="#CCCCCC" BorderColor="#999999" BorderStyle="Solid" BorderWidth="3px" CellPadding="4"
            AutoGenerateColumns="False" CellSpacing="2" ForeColor="Black" DataKeyNames="Data1" Width="70%" Visible="False" ShowFooter="True">
            <Columns>
                <asp:TemplateField>
                    <HeaderTemplate>
                        <asp:Label ID="SelectBox" runat="server" Text="Select"></asp:Label>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <asp:CheckBox ID="checker" runat="server" OnCheckedChanged="checker_CheckedChanged"/>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="Data1" HeaderText="Title1" ReadOnly="True" />
                <asp:BoundField DataField="Data2" HeaderText="Title2" ReadOnly="True" />
                <asp:BoundField DataField="Data3" HeaderText="Title3" />
            </Columns>
        </asp:GridView>

应该是这样的;

sqlCommand.Parameters.AddWithValue("@Item1", data1);
sqlCommand.Parameters.AddWithValue("@Item2", data2);
sqlCommand.Parameters.AddWithValue("@Item3", data3);

好的,完全不清楚您的例程 checker_CheckedChanged() 的作用?

您不需要 post-back 或任何复选框 - 但只需要一个提交按钮和代码存根

。那些 data1、data2 等无论如何都不会保留在内存中。所以,你不能使用那个例程——但你也不需要它。

除非网格有多个页面等,否则转储该例程。您可以随意选中网格中的任何行。然后你有一个提交按钮代码,这个例程只需要一点改变来检查所有 GV 行,并保存复选框值。

提交按钮代码 can/will 看起来像这样:

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        string connectionString = ConfigurationManager.ConnectionStrings["localDataB"].ConnectionString;

        using (var sqlConnection = new SqlConnection(connectionString))
        {
            sqlConnection.Open();

            // insert any row with check boxes into temp db

            string insertStatement = "INSERT into LocalDB (Item1, Item2, Item3) " + 
                                     "values (@Item1, @Item2, @Item3)";

            bool Data1, Data2, Data3;

            foreach (GridViewRow gRow in GridView1.Rows)
            {
                Data1 = Convert.ToBoolean(gRow.Cells[0].ToString());
                Data2 = Convert.ToBoolean(gRow.Cells[1].ToString());
                Data3 = Convert.ToBoolean(gRow.Cells[2].ToString());

                // save data if ANY is checked
                if (Data1 | Data2 | Data3)
                {
                    using (var sqlCommand = new SqlCommand(insertStatement, sqlConnection))
                    {
                        sqlCommand.Parameters.Add("@Item1", SqlDbType.Bit).Value = Data1;
                        sqlCommand.Parameters.Add("@Item2", SqlDbType.Bit).Value = Data2;
                        sqlCommand.Parameters.Add("@Item3", SqlDbType.Bit).Value = Data3;
                        sqlCommand.ExecuteNonQuery();
                    }
                }
            }
        }
    GVbind();
    }

我认为您不需要第一个例程。提交按钮可以循环GV,获取复选框值,如果选中3个中的任何一个,则进行插入。

但是,请记住,如果您使用模板化控件和 REAL 复选框,则 cells[] 集合仅适用于数据字段,那么您需要使用 findcontrol,而不是 cells[] 集合

编辑:

好的,首先,提供的信息表明正在使用模板字段。

但是,我们将首先解决 CheckBoxField 代码,因为它很难 google 并找到答案。所以我要包括那个答案。

如果复选框是数据字段,则您不能 change/edit,但您仍然可能想要遍历 GV 并获取这些值。

所以,对于数据字段,这样说:

<asp:CheckBoxField DataField="Active" HeaderText="Active" />

然后我们的代码必须像这样工作(你必须更深入地研究 cells() colleciton。

所以,代码变成这样:

          foreach (GridViewRow gRow in GridView1.Rows)
            {
                Data1 =(gRow.Cells[0].Controls[0] as CheckBox).Checked;
                Data2 = (gRow.Cells[1].Controls[0] as CheckBox).Checked;
                Data3 = (gRow.Cells[2].Controls[0] as CheckBox).Checked;

请注意 CheckBoxField 如何要求我们使用控件。

但是,如前所述,使用模板字段(任何类型和其中任何一种?)。

我们不使用 Cells[] 集合,模板化的列也不会出现在 cells 集合中。

因此,在很多(可能是大多数)情况下,我们可以期望将 CheckBox 控件作为模板化字段放入标记中。

典型的样子是这样的:

       <asp:GridView ID="GridView1" runat="server" class="table borderhide" 
            AutoGenerateColumns="false" DataKeyNames="ID">
            <Columns>
                <asp:BoundField DataField="FirstName"   HeaderText="FirstName"  />
                <asp:BoundField DataField="LastName"    HeaderText="LastName"   />
                <asp:BoundField DataField="City"        HeaderText="City"       />
                <asp:BoundField DataField="HotelName"   HeaderText="HotelName" HeaderStyle-Width="200"   />
                <asp:BoundField DataField="Description" HeaderText="Description" />

                <asp:TemplateField HeaderText="Smoking"  ItemStyle-HorizontalAlign="Center"  >
                    <ItemTemplate>
                        <asp:CheckBox ID="chkSmoking" runat="server"
                            Checked='<%# Eval("Smoking") %>' />
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Balcony"  ItemStyle-HorizontalAlign="Center"  >
                    <ItemTemplate>
                        <asp:CheckBox ID="chkBalcony" runat="server" 
                            Checked='<%# Eval("Balcony") %>' />
                    </ItemTemplate>
                </asp:TemplateField>

            </Columns>
        </asp:GridView>

所以在上面,第一个值(绑定字段)将在单元格集合中找到。

但是,上面的模板化字段?我们必须这样做:

                           "WHERE ID = @ID";
            foreach (GridViewRow gRow in GridView1.Rows)
            {
                CheckBox cSmoke = (CheckBox)gRow.FindControl("chkSmoking");
                CheckBox cBlacony = (CheckBox)gRow.FindControl("chkBalcony");
                int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];

                using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
                {
                    cmdSQL.Parameters.Add("@S", SqlDbType.Bit).Value = cSmoke.Checked;
                    cmdSQL.Parameters.Add("@B", SqlDbType.Bit).Value = cBlacony.Checked;
                    cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PKID;
                    cmdSQL.ExecuteNonQuery();
                }
            }

所以,我们的代码就变成了这样:

            foreach (GridViewRow gRow in GridView1.Rows)
            {
                Data1 =(gRow.FindControl("Active") as CheckBox).Checked;
                Data2 = (gRow.FindControl("Smoking") as CheckBox).Checked;
                Data3 = (gRow.FindControl("Balcony") as CheckBox).Checked;

当然,现在您将“文本控件”ID 替换为您使用的数据 1、2 和 3 ID。

其余代码应该相同。

今天的重要课程?

Post 一点标记 - 不是很大 - 但下次只需几行。你拯救了世界贫困,下次我可以post更好的回答。

所以规则是:

DataBound 字段 - 使用 cells[] 集合。

模板化字段 - 你必须使用 .FindControl("控件 ID 的名称在这里")

编辑#2

好的,到目前为止,现在的问题是:

我们有一些数据。如果用户检查第 1 行、5 行或 10 行,对于每个检查的行,我想写出 columns/values 我在其他 3 列 item1、item2、item3?

简单的问题!!!!

好的,所以唯一缺少的信息是什么数据类型字段类型是 item1、item2 和 item3?我们只是真的缺少那部分。

因此,如果复选框 = true,则将这 3 个项目列写入新的临时文件 table。

所以,现在的代码应该是:

            bool Data1, Data2, Data3;

            foreach (GridViewRow gRow in GridView1.Rows)
            {
                // get check box - 

                CheckBox ckSel = (gRow.FindControl("checker") as CheckBox);

                // save data if ANY is checked
                if (ckSel.Checked)
                {
                    Data1 = Convert.ToBoolean(gRow.Cells[0].Text);
                    Data2 = Convert.ToBoolean(gRow.Cells[1].Text);
                    Data3 = Convert.ToBoolean(gRow.Cells[2].Text);

                    using (var sqlCommand = new SqlCommand(insertStatement, sqlConnection))
                    {
                        sqlCommand.Parameters.Add("@Item1", SqlDbType.Bit).Value = Data1;
                        sqlCommand.Parameters.Add("@Item2", SqlDbType.Bit).Value = Data2;
                        sqlCommand.Parameters.Add("@Item3", SqlDbType.Bit).Value = Data3;
                        sqlCommand.ExecuteNonQuery();
                    }
                }
            }

如前所述,我现在多次声明,非模板化列仍然必须使用单元格集合。只有模板化列可以并且需要使用 FindControl。所有其他人必须继续使用 .Cells[] 集合。