Reputation: 1679
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
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
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.
<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
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
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