c# - 从 C# 添加新行时如何在 GridView 中添加删除链接?
问题描述
GridView 包含 ShowDeleteButton CommandField 以及其他文本框字段。
我在 C# 中向这个网格添加新行,为每个新添加的行添加新的文本框。添加新行时如何添加删除链接?
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" OnRowDataBound="Gridview1_OnRowDataBound" OnRowDeleting="Gridview1_RowDeleting" AutoGenerateColumns="false" ShowHeaderWhenEmpty="True" EmptyDataText="没有可用记录"> <asp: TemplateField HeaderText="Question"> <asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox> </asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" ReadOnly="true" Enabled="false" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="true" />
</Columns>
</asp:GridView>
private void AddNewRow()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Question", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Answer", typeof(String)));
foreach (GridViewRow row in Gridview1.Rows)
{
TextBox txtQuestion = (TextBox)row.FindControl("txtQuestion");
TextBox txtAnswer = (TextBox)row.FindControl("txtAnswer");
dr = dt.NewRow();
dr[0] = txtQuestion.Text;
dr[1] = txtAnswer.Text;
dt.Rows.Add(dr);
}
dt.Rows.Add(dt.NewRow());
dt.Rows[dt.Rows.Count - 1]["Question"] = "";
dt.Rows[dt.Rows.Count - 1]["Answer"] = "";
dt.AcceptChanges();
Gridview1.EditIndex = dt.Rows.Count - 1;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
解决方案
我建议您简单地将删除按钮添加到每一行。这样用户就可以轻松删除一行。
我还建议您使用数据表加载网格一次,然后将行添加到数据表 - 而不是网格。
我可以写出这种方法的一大堆优点。但一些优点是:
user does not get presented with multiple UI
user can edit any row on the grid - not have to hit edit, or save
a single un-do button can un-do all changes
a single SAVE button in ONE operation can save the WHOLE TABLE and change back to database
您添加一行的代码,以及设置和创建数据库的代码是分开的。这意味着您可以更改数据表,甚至可以让表的来源来自 sql server。如前所述,这还允许您保存整个表。结果是用户可以编辑一行,多行 - 非常类似于 Excel 电子表格的选项卡。完成后,他们可以:
hit save - all data back to database
hit un-do - un-do all their edits
hit + (add row) - add a new row to edit
hit delete key - it will delete the row in question (but UN-DO STILL ACTIVE!!!).
所以我们有一个更愉快的编辑方式。
因此,我建议您不要使用内置的删除按钮。放入您自己的按钮 - 无论如何它看起来会更好。(因此也不需要编辑按钮!!!!)。
所以,这是我们的标记:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Question">
<ItemTemplate>
<asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="+Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
当您放下按钮时(我使用了图像按钮),然后在代码编辑器中执行以下操作:
请注意在您点击“=”后如何正确,然后英特尔感知弹出 - 选择创建新事件。看起来什么都没有发生,但是如果你翻到后面的代码,你会看到一个代码子被生成了。您不能双击网格内的控件,但您可以为按钮创建一个事件单击 - 或者实际上以这种方式为标准 asp.net 控件创建任何事件。
为了拯救世界贫困,我还为该按钮添加了一个名为 MyRowID 的自定义属性 - 这将为该按钮设置行索引。
由于添加新行按钮在网格之外,所以我们可以双击该按钮,然后跳转到后面的代码。
现在,我们的代码如下所示:
private DataTable MyTable = new DataTable();
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
ViewState["MyTable"] = MyTable;
}
else
MyTable = ViewState["MyTable"];
}
public void LoadGrid()
{
MyTable.Columns.Add(new DataColumn("Question", typeof(string)));
MyTable.Columns.Add(new DataColumn("Answer", typeof(string)));
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void btnAddNewQuestionnaire_Click(object sender, EventArgs e)
{
DataRow MyRow = MyTable.NewRow;
MyRow("Question") = "my question";
MyRow("Answer") = "my ans";
MyTable.Rows.Add(MyRow);
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = sender;
int RowID = btn.Attributes.Item("MyRowID");
MyTable.Rows(RowID).Delete();
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
注意非常小心——我们在表单类中添加了一个 MyTable。因此,我们有一个持久化的表,并且我们针对该表进行操作。
事实上,如果数据来自 SQL 服务器,则可以使用与上述完全相同的设计。不仅更令人惊奇,而且我们现在可以在一次更新操作中将整个表保存 + 发送回 sql server。(您只需循环网格,将值放回表中,然后执行一次保存)。
而且上面没有凌乱的编辑按钮来编辑一行。我想我们可以为额外的标记添加一个删除构造框 - 用户如果他们碰撞或点击删除按钮,他们会得到一个确认对话框。该代码可能是这样的:
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>'
OnClientClick="return confirm('Delete this row?');"/>
所以现在当你点击删除行时,你会得到:
如果单击确定 - 它会删除 - 取消 - 没有任何反应。
因此,您可以通过以下方式节省大量代码和复杂性:
Persist the data table
Pass the row ID with the button
use the intel-sense trick to wire up a separate and specific button event code.
如前所述,如果您使用来自 sql server 的数据加载表,则上述整个过程也将起作用——“原样”代码的 REST 将起作用。
并将数据保存回sql server,然后您可以按照说明:
将数据从网格拉回该持久表。然后使用数据适配器,一个更新命令会将所有更改发送回 sql server。
推荐阅读
- html - 中心跨度在按钮内垂直
- javascript - 如何在 Flutter 中集成 Twilio JavaScript Video 库?
- android - 在项目中添加 Crashlytics 有 Dexguard
- sql - oracle函数延迟太高
- angular - Angular Slick-grid 列选择器图标隐藏在网格菜单图标后面,手动设置列宽
- python - python代码中关于async和await的问题
- php - “vendor\guzzlehttp\psr7\src\Uri.php:72”文件出现错误
- javascript - javascript - 如何清除“console.group”中的内容?
- android - 渲染 React Native ImageBackground 时出现语法错误
- python - 在python中生成具有规定度分布的网络(图)