Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

ListCtrl Operations

3.00/5 (2 votes)
8 May 2012CPOL2 min read 28.1K   744  
Add, Update, Delete operations on the ListCtrl.

Introduction

Hello Guys. This is my first ever article on CodeProject (or anywhere else) so I hope you don’t mind anything unusual.

This is a beginner’s article for adding, updating and deleting items froma ListCtrl in MFC Dialog based application.

Solution

First thing first, we make a standard MFC Dialog based application and make the GUI as you desire. Then we add the following variables to the controls.

  • Right click
    StudentId
    editbox and click Add Variable. In Category: select Value and name variable as: m_sStudentId. Type is CString.
  • Right click
    Name
    editbox and click Add Variable. In Category: select Value and name variable as: m_sName. Type is CString.
  • Right click
    ListCtrl
    and click Add Variable. In Category: select Control and name the variable as: m_ListOperations.
  • Go to the properties of ListCtrl and make sure that View property is set to: Report
  • Finally you can add three event handlers to the three buttons. Name them as you desire. I have
    OnAddItem(),
    OnUpdateItem(), 
    OnDeleteItem().

Now starting with the solution, it has four main functions namely: AddColumns_ToList(), AddItem(), UpdateItem() and DeleteItem().

Their names describe what they are meant to do. Here is the function body of AddColumns_ToList(). It is called in OnInitDialog().

C++
void CListCtrl_CommonActionsDlg::AddColumns_ToList()
{
        m_ListOperations.SetExtendedStyle(LVS_EX_GRIDLINES);

        LVCOLUMN col;
        int nCol;

        col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
        col.fmt = LVCFMT_LEFT;
        col.cx = 70;
        col.pszText = _T("ID");
        nCol = m_ListOperations.InsertColumn(0, &col);

        col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
        col.fmt = LVCFMT_LEFT;
        col.cx = 170;
        col.pszText = _T("Name");
        nCol = m_ListOperations.InsertColumn(1, &col);
}

Now here is the body for adding the items to the list. Remember that you are taking values from two editboxes.

C++
void CListCtrl_CommonActionsDlg::AddItem()
{
          UpdateData();

          LVITEM item;
          int nItem;

          item.mask = LVIF_TEXT;
          item.iSubItem = 0;

          //If 'm_listListOperations.GetItemCount() <= 0' evaluates to TRUE then 0, 
          //else  value returned by 'm_listListOperations.GetItemCount()'

          item.iItem = (m_ListOperations.GetItemCount() <= 0) ? 0 : m_ListOperations.GetItemCount(); 
          item.pszText = m_sStudentId.GetBuffer(1024);    //insert the StudentId from editbox to item

          nItem = m_ListOperations.InsertItem(&item);

          m_ListOperations.SetItemText(nItem, 1, m_sName);          //second column of the ListCtrl
          GetDlgItem(IDC_STUDENTID)->SetWindowTextW(_T(""));
          GetDlgItem(IDC_NAME)->SetWindowTextW(_T(""));
          GetDlgItem(IDC_STUDENTID)->SetFocus();
}

And now we update the record. For this, we use a structure named LVFINDINFO. We use the ListCtrl’s FindItem() method to find the item using the Id we get from the editbox. Using this methos, if the item is found then its information will be stored in the LVFINDINFO structure and it then returns an index of the found item. Here is how it is done.

C++
void CListCtrl_CommonActionsDlg::UpdateItem()
{
          UpdateData();
 
          LVITEM item;
          int nItem;
          CString str;
 
          GetDlgItem(IDC_STUDENTID)->GetWindowTextW(str);
 
          if (str != "")
          {
                   LVFINDINFO info;
                   info.flags = LVFI_PARTIAL|LVFI_STRING;
                   info.psz = str.GetBuffer(1024);
                   CString arr[3];
                   arr[0] = str;
                   arr[1] = m_sName;
 
                   int index = m_ListOperations.FindItem(&info);
                   if(index >= 0)
                   {
                             CHeaderCtrl* column = (CHeaderCtrl*)m_ListOperations.GetDlgItem(0);          
                   //OR:     CHeaderCtrl* column = m_listListOperations.GetHeaderCtrl();

                             int cols = column->GetItemCount();

                             item.mask = LVIF_TEXT;
                             item.iItem = index; 
                             item.pszText = m_sStudentId.GetBuffer(1024);
                             int nItem = index;
 
                             for (int i=0; i<cols; i++) //loop through the columns
                             {
                                if(i==0)
                                  continue;     //continue: because we do not want to update the first column
                                else
                                  m_ListOperations.SetItemText(nItem, i, arr[i]); //update the value
                             }
                             GetDlgItem(IDC_STUDENTID)->SetWindowTextW(_T(""));
                             GetDlgItem(IDC_NAME)->SetWindowTextW(_T(""));
                             GetDlgItem(IDC_STUDENTID)->SetFocus();
                   }
                   else
                   {
                             MessageBox(_T("No Item Found !!!"));
                             GetDlgItem(IDC_STUDENTID)->SetFocus();
                   }
          } 
          else
          {
                   MessageBox(_T("No Number Entered !!!"));
                   GetDlgItem(IDC_STUDENTID)->SetFocus();
          }
}

And now we delete the record. This is almost same as the previous function, the functionality being a different one. We have to find the item first and once found, we can delete it. Here is it

C++
void CListCtrl_CommonActionsDlg::DeleteItem()
{
          CString str;
          GetDlgItem(IDC_STUDENTID)->GetWindowTextW(str);
          if (str != "")
          {
                   LVFINDINFO info;
                   info.flags = LVFI_PARTIAL|LVFI_STRING;
                   info.psz = str.GetBuffer(1024);
 
                   int index = m_ListOperations.FindItem(&info);

                   if(index >= 0)
                   {
                             m_ListOperations.DeleteItem(index);
                             GetDlgItem(IDC_STUDENTID)->SetWindowTextW(_T(""));
                             GetDlgItem(IDC_STUDENTID)->SetFocus();
                   }
                   else
                   {
                             MessageBox(_T("No Item Found !!!"));
                             GetDlgItem(IDC_STUDENTID)->SetFocus();
                   }
          } 
          else
          {
                   MessageBox(_T("No Number Entered !!!"));
                   GetDlgItem(IDC_STUDENTID)->SetFocus();
          }
}

So this is how we add, update and delete items from a ListCtrl. Simple, isn’t it?

Points to Remember

  1. There could have been a lot of checks before doing these operations. For example: checking whether an ID already exists before we can add it to ListCtrl. But since the motive was to keep this sample as simple as possible, I think other such actions should not be a problem
  2. Please be aware that I do not know any drawbacks that this solution has. It just does the job for me perfectly. If there are any drawbacks, please share so that others may know whether to use this or not.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)