使用复选框在 gridview 中提交多行 (C#)
Submitting multiple rows in gridview with Checkboxes (C#)
我的目标是获取数据:
- 来自 sql 数据库
- 到网格视图
- 到本地 table
到目前为止,我能够使用存储过程将 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[] 集合。
我的目标是获取数据:
- 来自 sql 数据库
- 到网格视图
- 到本地 table
到目前为止,我能够使用存储过程将 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[] 集合。