在 Web 应用程序中使用 C# 在 asp:GridView 中复制粘贴一行
Posted
技术标签:
【中文标题】在 Web 应用程序中使用 C# 在 asp:GridView 中复制粘贴一行【英文标题】:Copy Paste a row in a asp:GridView using C# in a web application 【发布时间】:2021-11-10 20:05:28 【问题描述】:所以我有一个使用 GridView 的 Web 应用程序。 我们目前一次添加 1 个新的空白记录,填写并继续。有时需要输入的数据有多个需要复制的字段。有没有办法添加一个空白行,填充它,然后复制该行并将其粘贴回 GridView?
我看过克隆,但我还没有看到任何适用于 Web 应用程序的东西。感谢您的建议。
【问题讨论】:
您是在服务器上还是在客户端上添加行?有很多方法可以使用 GridView,也有很多方法可以添加一行。您只需要在新行上设置初始值。 目前我将空白行添加到sqlserver,然后填写并更新GV以及sql server。更新行后,我希望能够复制行并将其插入服务器,然后返回更新必要的字段。 【参考方案1】:嗯,一种方法,你可以在网格中添加一个复制按钮吗?
假设我们有这个网格:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID"
cssclass="table table-hover borderhide">
<Columns>
<asp:TemplateField HeaderText ="First Name">
<ItemTemplate>
<asp:TextBox ID="txtFirst" runat="server" Text = '<%# Eval("FirstName") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Last Name">
<ItemTemplate>
<asp:TextBox ID="txtLast" runat="server" Text = '<%# Eval("LastName") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="City">
<ItemTemplate>
<asp:TextBox ID="txtCity" runat="server" Text = '<%# Eval("City") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Active">
<ItemTemplate>
<asp:CheckBox ID="Active" runat="server" Checked = '<%# Eval("Active") %>'></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Copy">
<ItemTemplate>
<asp:ImageButton ID="cmdCopy" runat="server" Text="Copy"
ImageUrl="~/Content/copy1600.png" Height="32px" Width="32px"
OnClick="cmdCopy_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="cmdSave" runat="server" Text="Save" CssClass="btn-primary" OnClick="cmdSave_Click1" />
<asp:Button ID="cmdAdd" runat="server" Text="Add Row" CssClass="btn-primary" style="margin-left:20px" OnClick="cmdAdd_Click1"/>
<br />
所以,加载这个网格的代码
private DataTable rstPeople = new DataTable();
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
LoadGrid();
ViewState["MyTable"] = rstPeople;
else
rstPeople = (DataTable)ViewState["MyTable"];
public void LoadGrid()
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from People",
new SqlConnection(Properties.Settings.Default.TEST4)))
cmdSQL.Connection.Open();
rstPeople.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstPeople;
GridView1.DataBind();
以及添加行按钮代码:
protected void cmdAdd_Click1(object sender, EventArgs e)
GridToTable(); // user may have edits
// add a new row to the grid
DataRow OneRow = rstPeople.NewRow();
OneRow["Age"] = 0;
OneRow["Active"] = true;
rstPeople.Rows.Add(OneRow);
GridView1.DataSource = rstPeople;
GridView1.DataBind();
所以我们点击添加行,这给了我们这个:
所以,我们有那个空白行。但是,代替添加行,我们可以单击复制按钮,这将添加一行 - 但从当前复制。 (我想我们可以有一个复制 + 粘贴按钮 - 但这里的 UI 太多了)。
所以,添加行 = 添加空白行。
但是,复制行按钮 - 添加行 - 复制。
代码如下:
protected void cmdCopy_Click(object sender, ImageClickEventArgs e)
GridToTable(); // user might have done some editing
ImageButton cmdCopy = (ImageButton)sender;
GridViewRow gvRow = (GridViewRow)cmdCopy.Parent.Parent;
DataRow CopyFrom = rstPeople.Rows[gvRow.RowIndex];
DataRow OneRow = rstPeople.NewRow();
OneRow["Age"] = 0;
OneRow["FirstName"] = CopyFrom["FirstName"];
OneRow["LastName"] = CopyFrom["LastName"];
OneRow["City"] = CopyFrom["City"];
OneRow["Active"] = CopyFrom["Active"];
rstPeople.Rows.Add(OneRow);
GridView1.DataSource = rstPeople;
GridView1.DataBind();
现在我没有分享保存按钮的工作原理。
因此,用户现在可以添加新行。选项卡 - 编辑任何行。甚至复制一个新行(再次编辑一些)。
所以将整个混乱和网格保存回数据库,我们
Send Grid back to table
Send table back to database.
所以保存所有按钮是这样的:
protected void cmdSave_Click1(object sender, EventArgs e)
GridToTable();
// now send table back to database with updates
string strSQL = "SELECT ID, FirstName, LastName, City, Active from People WHERE ID = 0";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,
new SqlConnection(Properties.Settings.Default.TEST4)))
cmdSQL.Connection.Open();
SqlDataAdapter daupdate = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder cmdBuild = new SqlCommandBuilder(daupdate);
daupdate.Update(rstPeople);
再一次,真的很简单。并注意我们是如何不用模板等来打扰的(太乱了,而且确实比上面的代码少)。
我想您可以为新行添加一个“粘贴”图标,但如果用户必须选择一行并复制 - 不妨在一次操作中使其“添加行 + 复制”。
(它不是真正的复制按钮,而是更多的“复制行”按钮。
唯一没有发布的例程是 GridToTable。这是可行的,因为我们总是持久化表,但是 GV 中的任何编辑都必须发送回表,因此我们使用这个:
void GridToTable()
// pull grid rows back to table.
foreach (GridViewRow rRow in GridView1.Rows)
int RecordPtr = rRow.RowIndex;
DataRow OneDataRow;
OneDataRow = rstPeople.Rows[RecordPtr];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["City"] = ((TextBox)rRow.FindControl("txtCity")).Text;
OneDataRow["Active"] = ((CheckBox)rRow.FindControl("Active")).Checked;
如前所述,我想你可以放入一个“复制”按钮,并且只保留 + 保存行索引,然后有一个粘贴按钮 - 这将允许在任何行之间剪切 + 粘贴,而不仅限于新行。 (但是,这将允许用户很容易地覆盖现有行 - 从用户培训的角度来看,UI 再次过载。
上述技巧非常巧妙,因为任何新行、任何编辑都会通过一个简单的更新操作发送回数据库。 (而且提供者很聪明——如果一行没有被触及或改变,则不会生成 sql 更新语句。
由于在 ViewState 中持久化表,这整个技巧有效。请注意,如果您有数据分页器,则必须在此类导航中调用 GridToTable,或者实际上执行保存命令。
还要注意我们是如何选择 .parent.parent(网格行)的,并且再次没有使用 GV 事件模型。而且没有大量模板的东西,我们还避免了与多个模板混淆的世界贫困。
事实上,对于上述之外的任何网格,我都使用与上述完全相同的方法,但更喜欢 ListView。原因是您可以在标准的 asp.net 控件中拖放,而不必用“项目模板”围绕它们,这又是太多的工作和努力。
【讨论】:
哇哦...很多。让我消化一下,明天再回复。谢谢你的努力。非常感激!!我的gridview中的绑定字段通常是一样的吗?谢谢 当然,在我的示例中,行是数据绑定的。但我不使用额外的模板进行编辑或添加,因为我们真的不需要它们。但是,如果您仔细观察,我使用了模板列,但如果您使用绑定字段,那么我们使用 .cells[] 集合代替 FindControl - 代码将大致相同,但没有查找控件。我想我们也可以全力以赴,并添加一个 javascript 右键单击以复制 - 这是可能的,但这是简单的服务器端代码 - 如此干净和容易。 --- 唯一真正的区别是 .cells[] 集合是按列号 - 不是名称,但其他一切都是一样的。 很难复制选定的行。我看到你提到它应该是数字,但它是如何抓取的? 仔细查看我放入网格的按钮。仔细查看上面名为 cmdCopy_Click 的按钮存根事件。它首先将网格复制回表格(如果您允许网格编辑)。然后它获取/抓取您使用 cmdCopy.Parent.Parent 单击的行。那是用户单击的行。然后我从该行获取行索引,然后简单地添加一个新行,从该网格行复制值,然后重新绑定网格以显示我们刚刚添加的这个新行。所以 cmdCopy.Parent.Parent 是单击按钮事件如何获取当前网格行(我将其转换为 GridViewRow)。 获得整个网格行后,我可以将值从该网格行复制到新行。但是,由于我有表持久化,所以我只需将行索引获取到我正在更新的现有表。因此,我使用该表行中的值来设置用于添加的新行的值。设置值,将新行添加到数据表中,然后重新绑定网格以显示此新行。所以,我真的不必从网格行中获取/获取值,因为该网格行让我将索引行放入表中。但是,如果我没有持久表,我可以从网格中复制。以上是关于在 Web 应用程序中使用 C# 在 asp:GridView 中复制粘贴一行的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Visual Studio 2019 中使用 Xamarin Forms(UWP) 和 C# 创建 Web 应用程序
在 ASP.NET C# Web 应用程序中使用 ADO.NET 和 XML
如何在asp.net c# web应用程序中使用asp.net vb页面