简体   繁体   中英

How do I delete an item from a ListView using a custom DataSource?

I have a ListView with an IEnumerable<MyDocument> DataSource pulled from a method.

The code in myDocsList_ItemCommand() definitely runs, because the document is actually deleted. My problem is that the ListView still shows the (now deleted) document until the next page refresh, even though I have code to do myDocsList.Items.Remove(dataItem) .

The simplified .ascx is basically:

<asp:ListView id="myDocsList" runat="server" 
        OnItemDataBound="myDocsList_ItemDataBound" 
        OnItemDeleting="myDocsList_ItemDeleting" 
        OnItemCommand="myDocsList_ItemCommand">
    <LayoutTemplate>
        <table>
            <asp:Placeholder id="itemPlaceholder" runat="server" />
        </table>
    </LayoutTemplate>
    <ItemTemplate>
        <tr><td>
                <asp:LinkButton 
                    ID="delete" runat="server"
                    CommandName="Delete" CommandArgument="X"
                    OnClientClick="javascript:return confirm('...');">
                        Delete
                </asp:LinkButton>
        </td></tr>
    </ItemTemplate>
</asp:ListView>

The simplified .ascx.cs is basically:

protected void Page_Load(object sender, EventArgs e)
{
}

protected void Page_PreRender(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        IEnumerable<MyDocument> docs = getDocuments();
        myDocsList.DataSource = docs;
        myDocsList.DataBind();
    }
}

/* so we have the ID of the document we're deleting later on */
protected void myDocsList_ItemDataBound(object sender, 
                                        ListViewItemEventArgs e)
{
    var deleteButton = 
        (LinkButton) ((Control) e.Item).FindControl("delete");
    deleteButton.CommandArgument =
        ((MyDocument) e.Item.DataItem).id.ToString();
}

/* or we get "raised event ItemDeleting which wasn't handled" */
protected void myDocsList_ItemDeleting(Object sender, 
                                        ListViewDeleteEventArgs e)
{
}

/* do something here? */
//protected void myDocsList_ItemDeleted(Object sender, 
//                                      ListViewDeletedEventArgs e)
//{
//}

protected void myDocsList_ItemCommand(object sender, 
                                        ListViewCommandEventArgs e)
{
    if (e.CommandName == "Delete")
    {
        int docId = int.Parse(e.CommandArgument.ToString());
        deleteDocument(docId);
        ListViewDataItem dataItem = (ListViewDataItem) e.Item;
        myDocsList.Items.Remove(dataItem);
    }
}

I've been reading up on the ASP page lifecycle and a few related questions, but I'm reasonably inexperienced with ASP and a bit lost.

How do I get my ListView items to disappear on the PostBack instead of on the next page refresh?

You have to rebound data to your ListView in ItemCommand event, you can change your coding style as below:

//Create a new method for databind
void BindData()
{
    IEnumerable<MyDocument> docs = getDocuments();
    myDocsList.DataSource = docs;
    myDocsList.DataBind();
}

//Call databind method in your prerender event
protected void Page_PreRender(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        BindData();
    }
}

//Again bind data after delete operation
protected void myDocsList_ItemCommand(object sender,
       ListViewCommandEventArgs e)
{
    if (e.CommandName == "Delete")
    {
        int docId = int.Parse(e.CommandArgument.ToString());
        deleteDocument(docId);
        BindData();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM