Jamie
Jamie

Reputation: 1679

I can't get my DeleteCommand to work in ASP.net 4.0 VB

I have a ListView that lists features of a product on my website. I included an image button that is supposed to delete the specific feature, but my DeleteCommand won't do it. I have looked in my database, and the record is still there. Is there some code I need to add to the CodeBehind file to get this to work?

  <!-- Features --> 
 <asp:TabPanel id="tab1" class="infoHeader" runat="server" HeaderText="Features" DataKeyNames="MarketingID">
    <HeaderTemplate>Features</HeaderTemplate>
    <ContentTemplate>
        <ul class="info">
        <asp:ListView ID="lvFeatures" runat="server" DataSourceID="dsFeatures">
        <ItemTemplate>
          <li><%#Eval("FeatureTitle")%>
              <asp:ImageButton ID="DeleteFeatureButton" runat="server" Style="float:right;" AlternateText="" ImageUrl="../../images/delete.png" CommandName="Delete" OnCommand="ImageButton1_Command" OnClientClick="return confirm('Are you sure you want to delete this feature?')" />
          </li>
        </ItemTemplate>
        </asp:ListView>
        </ul>
    </ContentTemplate>
</asp:TabPanel>   

   Protected Sub ImageButton1_Command(ByVal sender As Object, ByVal e As CommandEventArgs)
    If TypeOf DirectCast(sender, ImageButton).Parent Is ListViewDataItem Then
        Dim item As ListViewDataItem = TryCast(DirectCast(sender, ImageButton).Parent, ListViewDataItem)
        If item IsNot Nothing Then
            lvFeatures.Items.RemoveAt(item.DisplayIndex)
        End If
    End If
End Sub

<!-- Gets all current features of this product -->
<asp:SqlDataSource ID="dsFeatures" runat="server" 
    ConnectionString="<%$ ConnectionStrings:ProductsConnectionString %>" 
    ProviderName="<%$ ConnectionStrings:ProductsConnectionString.ProviderName %>" 
    SelectCommand="SELECT m.MarketingID, f.FeatureID, f.FeatureTitle FROM Feature f INNER JOIN Marketing m ON m.MarketingData = f.FeatureID WHERE m.MarketingTypeID = 3 and m.ProductID = @ProductID"
    DeleteCommand="DELETE FROM Marketing WHERE MarketingID = @MarketingID">
    <SelectParameters>
        <asp:QueryStringParameter Name="ProductID" QueryStringField="id" />
    </SelectParameters>
    <DeleteParameters>
        <asp:QueryStringParameter Name="MarketingID" QueryStringField="id" />
    </DeleteParameters>
</asp:SqlDataSource>

Upvotes: 0

Views: 2810

Answers (3)

James Johnson
James Johnson

Reputation: 46047

To delete an item using the SqlDataSource, you have to do it like this:

Change the delete portion of your SqlDataSource control. Remove the QueryStringParameter from the DeleteParameters. You shouldn't have any parameters for the Delete:

<asp:SqlDataSource ID="dsFeatures" runat="server"                 
    ConnectionString="<%$ ConnectionStrings:ProductsConnectionString %>"                 
    ProviderName="<%$ ConnectionStrings:ProductsConnectionString.ProviderName %>"                 
    SelectCommand="SELECT m.MarketingID, f.FeatureID, f.FeatureTitle FROM Feature f INNER JOIN Marketing m ON m.MarketingData = f.FeatureID WHERE m.MarketingTypeID = 3 and m.ProductID = @ProductID"                
    DeleteCommand="DELETE FROM Marketing WHERE MarketingID = @MarketingID">                
    <SelectParameters>                
        <asp:QueryStringParameter Name="ProductID" QueryStringField="id" />                
    </SelectParameters>                               
</asp:SqlDataSource> 

Add MarketingID as a data key to your ListView:

<asp:ListView ID="lvFeatures" runat="server" DataSourceID="dsFeatures" DataKeyNames="MarketingID">    
    <ItemTemplate>    
        <li>    
            <%#Eval("FeatureTitle")%>    
            <asp:ImageButton ID="DeleteFeatureButton" runat="server" Style="float:right;" AlternateText="" ImageUrl="../../images/delete.png" CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this feature?');" />        
        </li>    
    </ItemTemplate>    
</asp:ListView> 

To debug the code before the delete occurs, add an OnDeleting event handler to the SqlDataSource control. You can then set a breakpoint before the delete to verify the code that will be executed.

protected void dsFeatures_Deleting(object sender, SqlDataSourceCommandEventArgs e)
{
    string commandText = e.Command.CommandText;
}

Upvotes: 1

James Johnson
James Johnson

Reputation: 46047

You didn't actually assign the command event handler. You should also assign the index to the command argument.

EDIT: Just noticed that the ImageButton is contained in a ListView, which is contained in a TabPanel. Revised code to delete item from ListView.


Original method for removing the item from list

<asp:ImageButton ID="ImageButton1" runat="server" CommandName="Delete" CommandArgument='<%#Container.ItemIndex%>' OnCommand="ImageButton1_Command" ...>

In the code behind:

EDIT: Removed c# code and included VB.NET syntax EDIT: Changed method from private to protected

Protected Sub ImageButton1_Command(sender As Object, e As CommandEventArgs)
    If e.CommandName.ToUpper() = "DELETE" Then           
       lvFeatures.Items.RemoveAt(DirectCast(e.CommandArgument, Integer))
    End If
End Sub

EDIT: Added alternative methods for deleting item, because Container.ItemIndex doesn't seem to be working properly in his code


Alternative ways of removing the item from the list

Remove the command argument altogether, like this:

<asp:ImageButton ID="ImageButton1" runat="server" CommandName="Delete"  OnCommand="ImageButton1_Command" ...>

Alternative #1: Remove item directly

Protected Sub ImageButton1_Command(sender As Object, e As CommandEventArgs)
    If TypeOf DirectCast(sender, ImageButton).Parent Is ListViewDataItem Then
        Dim item As ListViewDataItem = TryCast(DirectCast(sender, ImageButton).Parent, ListViewDataItem)
        If item IsNot Nothing Then
            lvFeatures.Items.Remove(item)                
        End If
    End If
End Sub

Alternative #2: Remove item at display index

Protected Sub ImageButton1_Command(sender As Object, e As CommandEventArgs)
    If TypeOf DirectCast(sender, ImageButton).Parent Is ListViewDataItem Then
        Dim item As ListViewDataItem = TryCast(DirectCast(sender, ImageButton).Parent, ListViewDataItem)
        If item IsNot Nothing Then                               
            lvFeatures.Items.RemoveAt(item.DisplayIndex)
        End If
    End If
End Sub

Upvotes: 0

ScottE
ScottE

Reputation: 21630

If you attach a datakeynames property to the listview it should wire that up for you automatically.

<asp:ListView ID="lvFeatures" runat="server" DataSourceID="dsFeatures"
 DataKeyNames="MarketingID">

This is assuming that the id is part of the data set. You'll have to change the paramter in the <DeleteParameters> to just a regular parameter, not a querystring param.

Upvotes: 2

Related Questions