How to delete selected row of a List Control in MFC?

6.9k views Asked by At

I want to delete selected row of list control in MFC. I have created a Delete Button, So If any row (it could be one or more than one row) is/are selected and I press delete button that/those rows should be deleted. If lets say there are 100 rows and I select rows from 50-60, all the rows in this range should be deleted and rest of rows should have indexes from 1 to 90. means indexing should be proper after deletion also.

3

There are 3 answers

0
sergiol On

When deleting a multiple selection having several items I prefer to do it like this:

int nItem = -1;
while ((nItem = m_list.GetNextItem(nItem, LVNI_SELECTED)) != -1)
{
    if (m_list.DeleteItem(nItem))
        nItem--;
}

Notice the important nItem--; line

UPDATE

I had to give up from this approach as the ItemData of an element gots fucked up. If I remove the nth element then the n+1 element will be my new nth. That element has a completely screwed up Itemdata.

UPDATE 2

I also tried with

int nItem = -1;
while ((nItem = m_list.GetNextItem(-1, LVNI_SELECTED)) != -1)
{
    m_list.DeleteItem(nItem);
}

This approach also has the problem of screwing the Itemdata I reported before.

0
sergiol On

The following approach worked perfecly for me:

std::stack< int > items;
int nItem = -1;

while ((nItem = myListCtrl.GetNextItem(nItem, LVNI_SELECTED)) != -1)
{
    items.push(nItem);
}

bool removed = false;
while (!items.empty())
{
    nItem = items.top();

    if (myListCtrl.DeleItem(nItem))
        removed = true;

    items.pop();
}

if (removed)
    // update some application state;

Explanation: When you remove things from the end to the start, you do not have to worry about the validity of positions. As the CListCtrl does not provide a GetPrevItem or any other way to get items in the reverse order, you need to store them in a collection where you can have that reverse order.

The most practical way to do it is to use a stack. Due to the way it works, you will put things in there in the normal order, and when you retrieve things they are automatically in reverse order.

2
Edward Clements On

Adapted from this MSDN article:

UINT i, uSelectedCount = m_myListCtrl.GetSelectedCount();
int  nItem;
if (uSelectedCount > 0)
    for (i=0; i < uSelectedCount; i++)
    {   nItem = m_myListCtrl.GetNextItem(-1, LVNI_SELECTED);
        ASSERT(nItem != -1);
        m_myListCtrl.DeleteItem(nItem); 
    }