我无法在gridview上获取删除链接按钮

时间:2016-12-14 13:11:56

标签: c# sql asp.net gridview

Latest error 我目前正在使用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();
    }

当我运行该页面并单击任何子项旁边的“删除”时,出现以下错误:

Error

我将包含我的.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"].ConnectionStr‌​ing;
        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>

2 个答案:

答案 0 :(得分:0)

嗯,您正在处理GridView的删除事件,而不是按钮的点击。所以你的发件人实际上是一个GridView控件,你不应该把它转换为LinkBut​​ton。

此外,您没有分配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)

senderGridView中的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"].ConnectionStr‌​ing))
    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();
}