我目前正在使用Visual Studio在C#中创建一个asp.net Web应用程序。我有一个gridview,显示数据库表中的数据,我已经在我的.cs页面中手动添加了数据源,因为我已经将孩子的DOB转换为年龄,从而使我能够使用年龄组的下拉列表过滤gridview。这一切都很好,我唯一的问题是让删除链接按钮工作。如果点击,我需要它从数据库表中完全删除子项。
我首先在设计模式中转到gridview,添加新列 - >按钮字段(按钮类型'链接',命令名称'删除')然后在我的.cs页面中添加以下代码:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
LinkButton lnkRemove = (LinkButton)sender;
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "delete from children where " +
"childID=@childID";
cmd.Parameters.Add("@childID", SqlDbType.VarChar).Value
= lnkRemove.CommandArgument;
GridView1.DataSource = source;
GridView1.DataBind();
}
当我运行该页面并单击任何子项旁边的“删除”时,出现以下错误:
我将包含我的.cs页面的完整代码以及我的源代码。有人可以帮我弄清楚为什么我收到错误,为什么删除按钮不会删除没有问题?提前谢谢。
完全.CS代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
namespace Coursework
{
public partial class Testy1 : System.Web.UI.Page
{
//create a datasource
SqlDataSource source = new SqlDataSource();
protected void Page_Load(object sender, EventArgs e)
{
//always set some defaults for the sqldatasource
source.ID = "source1";
source.ConnectionString = ConfigurationManager.ConnectionStrings["newregDBConnectionString"].ConnectionString;
source.SelectCommand = "SELECT firstname, dob, DATEDIFF(hour, dob, GETDATE()) / 8766 AS age FROM children ORDER BY age";
if (!IsPostBack)
{
//bind the grid
GridView1.DataSource = source;
GridView1.DataBind();
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
//the new database query, now with where clause
source.SelectCommand = "SELECT firstname, dob, DATEDIFF(hour, dob, GETDATE()) / 8766 AS age FROM children WHERE (DATEDIFF(hour, dob, GETDATE()) / 8766 BETWEEN @start AND @end) ORDER BY age";
//get the end age from the dropdown and cast as int
int end = Convert.ToInt32(DropDownList1.SelectedValue);
//get the start int for the filter
int start = end - 2;
//if the filter is resetted, make sure the query returns all ages
if (end == 5)
{
start = 5;
end = 99;
}
//replace the parameters in the query
source.SelectParameters.Add("start", start.ToString());
source.SelectParameters.Add("end", end.ToString());
//rebind the grid
GridView1.DataSource = source;
GridView1.DataBind();
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
LinkButton lnkRemove = (LinkButton)sender;
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "delete from children where " +
"childID=@childID";
cmd.Parameters.Add("@childID", SqlDbType.VarChar).Value
= lnkRemove.CommandArgument;
GridView1.DataSource = source;
GridView1.DataBind();
}
}
消息来源代码:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Testy1.aspx.cs" Inherits="Coursework.Testy1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<p></p>
<p></p>
<p></p>
<p></p>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Text="Filter age" Value="5"></asp:ListItem>
<asp:ListItem Text="5 - 7" Value="7"></asp:ListItem>
<asp:ListItem Text="8 - 10" Value="10"></asp:ListItem>
<asp:ListItem Text="11 - 13" Value="13"></asp:ListItem>
<asp:ListItem Text="14 - 16" Value="16"></asp:ListItem>
</asp:DropDownList>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" OnRowDeleting="GridView1_RowDeleting" >
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<%# Eval("firstname") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DOB">
<ItemTemplate>
<%# Convert.ToDateTime(Eval("dob")).ToString("d MMMM yyyy") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Age">
<ItemTemplate>
<%# Eval("age") %>
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField CommandName="Delete" Text="Delete" />
</Columns>
</asp:GridView>
</asp:Content>
答案 0 :(得分:0)
嗯,您正在处理GridView的删除事件,而不是按钮的点击。所以你的发件人实际上是一个GridView控件,你不应该把它转换为LinkButton。
此外,您没有分配CommandArgument。应该是这样的:
<asp:ButtonField CommandName="Delete" Text="Delete" CommandArgument='<%# Eval("childID") %>' />
但即使你这样做,这也无济于事,因为CommandArgument不会与Delete甚至args一起传递。因此,您有两种选择。
首先切换到处理RowCommand事件:
OnRowDeleting="GridView1_RowCommand"
在那里,您需要检查该命令实际上是否为删除命令,并使用命令arg删除:
if (e.CommandName == "Delete")
{
// parse e.CommandArgument and delete
}
其次是为行定义主键。
DataKeyNames="childID"
这将通过删除事件的事件参数提供:
e.Keys
在这种情况下,您根本不需要设置CommandArgument。
答案 1 :(得分:0)
sender
是GridView
中的RowDeleting
,而不是按钮,因此您的广告投放失败。
如果您要指定DataKeyNames
,则可以使用GridView的DataKeys
属性:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
DataKeyNames = "childID"
OnRowDeleting="GridView1_RowDeleting" >
代码隐藏:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string childId = GridView1.DataKeys[e.RowIndex].Value.ToString();
string deleteSql = @"DELETE FROM Children
WHERE childID = @childID;";
using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["newregDBConnectionString"].ConnectionString))
using(var cmd = new SqlCommand(deleteSql, con))
{
cmd.Parameters.Add("@childID", SqlDbType.VarChar).Value = childId;
con.Open();
int deleted = cmd.ExecuteNonQuery();
}
GridView1.DataSource = GetDataSource(); // provide a method that returns it
GridView1.DataBind();
}