Deleting a Multiple Selection of Rows in a Listview Control

Optional Reading

With this article, I don't want to give you just nice code to copy and paste for your application's source code. I think that you do not learn very much from "sweet snippets" and many coders, including me, do sometimes only paste the code as mentioned above to get their application with the desired feature running. You can still just copy and paste the code out of this article, but I'll do my best to explain why I chose several ways of programming and show you some errors I come up with during my development of this function to help you to learn something.

Introduction

This article explains how it is possible to delete more than one selected row of a listview control in report mode. It is not as easy as it seems, but if you have some experience with programming for Windows and MFC, you should understand my source code and my explanation very quickly. At first, we will look at some simple basics—deleting one selected row.

As you can see, we are using a member function of the CListCtrl class to obtain the index of the selected row. After that, we check whether the result is not -1 because this would mean that no item is selected. If the result is zero or higher than zero, we delete the row with the member function DeleteItem of the CListCtrl class. This works fine for one-row selections, but if we select more than one item, the only row that's going to be deleted is the row we selected first.

In our new function, we first get the number of selected rows. If the result equals zero, we jump out of the code. But, if it's higher than zero, we go on with the code and retrieve the position of the first selected row. After that, we execute the loop as long as GetNextSelectedItem doesn't return -1, which means that there are no rows available that are selected, too. If you are using this code, you will notice that it does not work correctly because of the fact that the row indices in the listview control are changing if one or more items are deleted. As a result, not all rows or different rows than we have selected are going to be deleted. Take a short break and think about why this function does not work correctly... or just read on.

Here are some pictures that explain what happens if you are using the currently created function.

Image 1: The Listview control with several rows selected.

Image 2: This picture shows what happens if we delete the first row in our DeleteSelectedRows() method.

As you can see from Image 2, all the row indices are changing if the first row in the listview control is deleted. Due to this behaviour, the selected row indices are no longer valid. In this example, we want to delete row 1 after row 0, but the index of this row changed from 1 to 0, so row 2 will be deleted instead. During thinking about a solution for this problem, I came up with the idea to delete the rows with the highest index first. If we are deleting the rows with the highest indices first, the indices of the indices of other rows won't get changed.

We are using a dynamic allocated array to store the indices of the selected rows inverted. That means that the row indices will be stored from the highest index to the lowest index. Finally,we just have to loop through all row indices and delete them.

The End

This the end of the explanation how it's possible to delete more than one selected row at once. You can download the commented source code and the executable of a demo application that uses the routine at the bottom of the page. In the demo application, it's possible to delete rows by using the menu or by pressing the Delete key on the keyboard.

At the very end of my article, I want to thank the community of codeguru.com for providing a lot of cool coding stuff and codeguru.com for giving developers a platform to help other developers. I hope that some of you have learned something from my article.

I am looking forward to your comments, critiques, and questions about my article. If you want contact me, write a message to daniel-bartsch@arcor.de.

Top White Papers and Webcasts

Today, users, applications, and data exist in more places than ever before, creating an unprecedented challenge for IT. How can IT achieve the flexibility and agility it needs to offer multiple types of applications in multiple locations? To better serve business demands for information everywhere, enterprises must develop new strategies for optimizing multiple kinds of networks. Read this white paper to learn how hybrid networks provide an unprecedented level of network dynamism, enterprise agility, and the …

As virtualization becomes the norm throughout organizations of nearly all sizes, and as more organizations look to private cloud solutions, IT decision makers are increasingly in need of ways to keep storage costs and complexity under control in the face of often-runaway virtual machine (VM) sprawl. Application-aware storage is designed to help achieve these important goals. Read this white paper to learn how application-aware storage allows you to gain VM-level visibility into application performance and …