0

我正在尝试为我的 Gridview 删除一列,并在我选择复选框并单击删除按钮时从服务器资源管理器中的数据库中删除它,但是每当我单击删除按钮时,页面就会刷新并且数据在我的数据库中没有被删除。不确定这是否是从数据库中删除它的正确方法。运行代码时没有显示错误消息。

这是我的FAQ.aspx:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head runat="server">  
    <title></title>  
</head>  
<body>  
    <form id="form1" runat="server">  
    <div>  
      
        <table style="width:100%;">  
            <tr>  
                <td>  
                     </td>  
                <td>  
                     </td>  
                <td>  
                     </td>  
            </tr>  
            <tr>  
                <td>  
                     </td>  
                <td>  
                    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Width="468px">  
                        <Columns>  
                            <asp:TemplateField HeaderText="Type">  
                                <EditItemTemplate>  
                                    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("type") %>'></asp:TextBox>  
                                </EditItemTemplate>  
                                <ItemTemplate>  
                                    <asp:Label ID="Label1" runat="server" Text='<%# Bind("type") %>'></asp:Label>  
                                </ItemTemplate>  
                            </asp:TemplateField>  
                            <asp:TemplateField HeaderText="Description">  
                                <EditItemTemplate>  
                                    <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("description") %>'></asp:TextBox>  
                                </EditItemTemplate>  
                                <ItemTemplate>  
                                    <asp:Label ID="Label2" runat="server" Text='<%# Bind("description") %>'></asp:Label>  
                                </ItemTemplate>  
                            </asp:TemplateField>  
                            <asp:TemplateField HeaderText="Email">  
                                <EditItemTemplate>  
                                    <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("Email") %>'></asp:TextBox>  
                                </EditItemTemplate>  
                                <ItemTemplate>  
                                    <asp:Label ID="Label3" runat="server" Text='<%# Bind("Email") %>'></asp:Label>  
                                </ItemTemplate>  
                            </asp:TemplateField>  
                            <asp:TemplateField HeaderText="Role">  
                                <EditItemTemplate>  
                                    <asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("role") %>'></asp:TextBox>  
                                </EditItemTemplate>  
                                <ItemTemplate>  
                                    <asp:Label ID="Label4" runat="server" Text='<%# Bind("role") %>'></asp:Label>  
                                </ItemTemplate>  
                            </asp:TemplateField> 
                            <asp:TemplateField>  
                                <EditItemTemplate>  
                                    <asp:CheckBox ID="CheckBox1" runat="server" />  
                                </EditItemTemplate>  
                                <ItemTemplate>  
                                    <asp:CheckBox ID="CheckBox1" runat="server" />  
                                </ItemTemplate>  
                            </asp:TemplateField>  
                        </Columns>  
                    </asp:GridView>  
                </td>  
                <td>  
                     </td>  
            </tr>  
            <tr>  
                <td>  
                     </td>  
                <td>  
                    <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Delete" />  
                </td>  
                <td>  
                     </td>  
            </tr>  
        </table>  
      
    </div>  
    </form>  
</body>  
</html>  

这是我的 FAQ.aspx.cs:

        public void refreshdata()
        {


            SqlCommand cmd = new SqlCommand("select * from Enquiry", con);
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            sda.Fill(dt);
            GridView1.DataSource = dt;
            GridView1.DataBind();

        }

        protected void Button1_Click(object sender, EventArgs e)
        {

            foreach (GridViewRow gvrow in GridView1.Rows)
            {

                CheckBox chck = gvrow.FindControl("CheckBox1") as CheckBox;
                if (chck.Checked)
                {

                    var Label = gvrow.FindControl("Label1") as Label;


                    SqlCommand cmd = new SqlCommand("DELETE FROM Enquiry WHERE enquiryID=@id", con);
                    cmd.Parameters.AddWithValue("@id", int.Parse(Label.Text));


                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();
                    refreshdata();
                    


                }
            }


        }
    }
}
4

2 回答 2

0

根本不清楚为什么(什么) Bind("type") 在这里做什么。

我会改变这个:

 <asp:TemplateField>
     <EditItemTemplate>  
        <asp:CheckBox ID="CheckBox1" runat="server" />  
          </EditItemTemplate>  
       <ItemTemplate>  
          <asp:CheckBox ID="CheckBox1" runat="server" />  
       </ItemTemplate>  
 </asp:TemplateField>  

至:

 <asp:TemplateField>
    <ItemTemplate>  
      <asp:CheckBox ID="CheckBox1" runat="server"
       MyPKID = '<%# Eval("enqueirID") %>' />  
       </ItemTemplate>  
 </asp:TemplateField>  

编辑:好的,看起来你确实在使用编辑模板(你能确认一下吗? - 再次回答这些问题很重要。如果你真的在使用编辑模板,那么我想你可以/将会有这个:

  <asp:TemplateField>
    <ItemTemplate>  
      <asp:CheckBox ID="CheckBox1" runat="server"
       MyPKID = '<%# Eval("enqueirID") %>' />  
       </ItemTemplate>  

    <EditItemTemplate>  
      <asp:CheckBox ID="CheckBox1" runat="server"
       MyPKID = '<%# Eval("enqueirID") %>' />  
       </EditItemTemplate>  

 </asp:TemplateField>  

现在在这段代码中,您可以获取/获取/拥有 PK 值:

CheckBox chck = gvrow.FindControl("CheckBox1") as CheckBox; 如果(检查。检查){

               int MyPK = chck.Attributes.Item("MyPKID");
               debug.print(MyPK);

              SqlCommand cmd = new SqlCommand("DELETE FROM Enquiry WHERE enquiryID=@id", con);
                cmd.Parameters.Add("@id", sqlDbType.Int).Value = MyPK


                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();                    

换句话说,因为我们在网格中没有一列具有/显示/包含/保存我们需要/想要的 PK 值?然后只需将 PK 列作为属性添加到复选框控件。

但是我们有两个人在评论中询问“类型”。我们只是不认为列名“Type”与行的实际数据库 PK id 和名为 enquiryID 的列有任何关系(我想可能是这样,你可以在每个人的面对这里,真的是这样!!!)。

现在,我们有两个人在评论中反复询问数据库中“Type”的值是否真的与 enquiryID 的值相同。(我想它可能是,但这是一个巨大的混乱在这里)。

我们都只是在这里要求澄清。

我建议您只需使用 Eval("您想要的数据库列的名称就在此处") 就可以了。

如前所述,通常我们没有列或不想在网格视图中显示/显示数据库中的 PK ID。因此,您可以隐藏该列以进行显示,或者更好的是,只需为复选框控件添加自定义属性,然后将 PK id 包含在复选框控件中。由于我们在复选框上进行了查找控件,并且我们没有单独的行控件来保存 pk id,那么我们不妨在 ALSO 包含/具有/保存 PK id 值的复选框上设置一个自定义属性该控件中的 enquiryID 。

我在网格行中看不到任何控件具有/持有/包含我们显然需要并且将用于从数据库中删除 ONE 行的所有非常重要的 PK id。

编辑: - - - - - - - - - - - - - - - - - -

好的,所以这里真正重要的是正在使用编辑模板这一事实(我在您发布的标记中没有看到“显示编辑”按钮 = true。我注意到这个关于 EditTemplate 的问题,因为这会在所有东西附近炸毁那将非常简单。

如果您使用 EditTemplate,那么您是否只希望在用户点击编辑时更改复选框?你必须回答并决定这个问题。

为什么编辑模板是一笔巨大的交易?好吧,只需删除一个未绑定的复选框很简单 - 容易。但如果你真的有一个编辑模板?好吧,如果您点击复选框,然后点击“编辑”来编辑行,那么复选框的值不会从模板传输到编辑模板。(原因:复选框未绑定到任何数据)。

如果你赶时间 - 只是必须让它工作?然后我会在数据库中添加一列,并作为新列的复选框。这样您就可以从数据库中获取/获取值,并基于该值进行删除。

我根本无法强调拥有未绑定复选框以及正在运行的编辑模板的交易有多大!- 非常重要,也是非常大的挑战。

所以,首先:既然你有一个编辑模板,那么普通模板(itemTempalte)中的复选框应该被禁用。毕竟,如果你强迫用户使用“编辑”和“编辑模板”,那么值应该只改变。

如前所述,只需一个模板 - 您可以选中这些框。您的删除按钮可以循环 gv 行,您可以执行查找控件,您将获得选中的值。

但是,如果需要编辑模板?那么我们必须坚持选中的值,因为从模板更改为编辑模板(然后更新和退出编辑模板)意味着我们必须持有、保留和持久化复选框值(否则它们将丢失!!!) .

如果您分享这样一个事实,即当您选中该框并从“编辑”模式切换到正常模式时,该复选框丢失了,那将是非常壮观的!!!

好的,再一次,如果我们真的需要并且打算使用编辑模板?然后我们必须连接一些代码来保存和持久化复选框的值。我们可以使用任一行 ID,但更好的是使用行 PK 值。

所以,现在让我们输入一些代码来保存复选框值。有一个很好的数字,但这是我过去使用的:

{
private Dictionary<int, bool> MyDict;

protected void Page_Load(object sender, System.EventArgs e)
{
    if (System.Web.UI.Page.IsPostBack == false)
    {
        MyDict = new Dictionary<int, bool>();
        System.Web.UI.Page.Session["MyChecked"] = MyDict;
    }
    else
        MyDict = System.Web.UI.Page.Session["MyChecked"];
}
}

所以请注意我是如何在“类”级别创建 MyDict 的。我当然也将 MyDict 推入 session() 和/或如果不是第一页加载,那么我从 session() 恢复 MyDict。如果你不运行 session(),你也可以很好地使用 ViewState,而 ViewState 在这里可能是更好的选择。

因此,当您选中一个框(或取消选中)时,我们只需将值保存到我们方便的花花公子 MyDict 中。

因此,在标记中,添加以下内容:

       <ItemTemplate>
          <asp:CheckBox ID="CheckBox1" runat="server" 
              OnCheckedChanged="CheckBox1_CheckedChanged"
              AutoPostBack="true" 
              Checked='<%# GetCheck(Eval("ID")) %>'
              MyPKID = '<%# Eval("ID") %>'
           />
       </ItemTemplate>

因此,如前所述,我仍在为复选框控件使用自定义 PKID 属性。(只是节省了一些代码,并且不得不尝试在网格视图中弄乱行索引)。

请注意,我们添加了一些内容,例如 autopostback=true。我们添加了获取 PK 行 ID 的 MyPKID。我使用了“ID”,但您当然会使用您的 PK 行 ID -(enquiryID)。

请注意,我们为复选框连接了一个事件。当我们选中(或取消选中)时,我们会将选中的框值保存到 MyDict。

所以复选框事件的代码存根是这样的:

protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = sender;

MyDict(chk.Attributes.Item("MyPKID")) = chk.Checked;
}

所以注意很多代码。它只是添加(或设置)带有 PK ID 和设置的 MyDict 集合。我真的很喜欢集合上的“字典”,因为如果不存在,设置将添加一个新的字典对,或者如果它确实存在则简单地覆盖。

因此,只需选中复选框即可维护上述持久化的“MyDict”。

现在剩下的唯一部分是将复选框绑定到返回复选框设置的函数。

代码再次非常简单。我们只需将 PK 传递给函数,并返回 true 或 false。

public bool GetCheck(int MyPKID)
{

// check for check box in this row
if (MyDict.ContainsKey(MyPKID))
{
    Debug.Print("key found = " + MyPKID);
    return MyDict(MyPKID);
}
else
    return false;
}

所以现在我们有能力根据 PK id “返回”复选框的值。

所以请注意复选框中的这个表达式:

<asp:CheckBox ID="CheckBox1" runat="server" 
      OnCheckedChanged="CheckBox1_CheckedChanged"
      AutoPostBack="true" Checked='<%# GetCheck(Eval("ID")) %>'
      MyPKID = '<%# Eval("ID") %>'
 />

请注意,在上面,我们如何简单地调用 + 使用来自后面网页代码的自定义“公共”函数。我们调用“GetCheck()”,但将 PK ID 传递给它(如前所述,我使用的是“ID” - 您将使用您的 PK id。

那么上面的额外代码呢?只需要因为两个主要原因:

You are using both Edit template and item template.
AND ALSO that the check box is NOT bound, so you have to manage
the state in code.

如前所述,如果这只是一个网格 - 并且没有编辑模板?然后你可以/可以只是简单地取消绑定复选框,然后你就可以参加比赛了。

是编辑模板和模板之间的交互搞砸了。

此外,我没有看到您的编辑按钮,以及您如何在正常模式和编辑模式之间切换 - 但这非常表明该复选框应该在正常模式下禁用,并且仅在“编辑”模式下启用。但是,如果您想要或允许在不必先使用编辑模式的情况下选中该框,上面“按原样”发布的代码和想法应该可以正常工作。如果您不在乎,那么您不需要为两个模板重复一个复选框 - 它会按照上面的方法正常工作。

于 2021-02-12T16:45:35.437 回答
0

我认为您不会因此而删除任何内容:

<asp:Label ID="Label1" runat="server" Text='<%# Bind("type") %>'></asp:Label>
// not sure this is what should be here --------------^^^^

// because you are using this value here ----------------------------vvv
SqlCommand cmd = new SqlCommand("DELETE FROM Enquiry WHERE enquiryID=@id", con);
cmd.Parameters.AddWithValue("@id", int.Parse(Label.Text));
// remember that Label is "Label1" ----------^^^^^^^^^^

简而言之,您的Label.Text不包含一个enquiryID,而是另一个值,取自type列。

于 2021-02-11T15:23:17.427 回答