Click here to Skip to main content
15,881,559 members
Articles / Desktop Programming / MFC
Tip/Trick

Moving Listbox Items Up and Down

Rate me:
Please Sign up or sign in to vote.
4.50/5 (5 votes)
13 Oct 2013CPOL 28.1K   458   9   7
For single or multiple selection CListBox

Image 1

Image 2

Introduction

After some search without success about doing up / down of CListbox items (with multiple selection), here is my solution.

The code below is doing roll up/down: First item goes to last position on UP; last item goes to first position on DOWN.

Using the Code

Insert the 2 files in your project:

C++
Function_1D.h and Function_1D.cpp 

Example of use:

C++
//----------------------------------------------------------------------------
void CListBoxMoveItem::OnBnClickedButton20()    //^
{
    Func_1::ListBox_UpItem( &m_cListBox );    //Up selected items
    UpdateData( FALSE );
}

//----------------------------------------------------------------------------
void CListBoxMoveItem::OnBnClickedButton21()    //v
{
    Func_1::ListBox_DownItem( &m_cListBox  );    //down selected items
    UpdateData( FALSE );
}

The code is in a separate function file Function_1D:

C++
//Function_1D.h
namespace Func_1 
{
BOOL ListBox_UpItem( CListBox* pListBox );   //Up selected items
BOOL ListBox_DownItem( CListBox* pListBox ); //down selected items
} 

//Function_1D.cpp
//-----------------------------------------------------------------------
BOOL Func_1::ListBox_UpItem( CListBox* pListBox )    //Up selected items
{
    int iPos = 0;
    int iLigne0 = -1;
    int iLigne1 = 0;
    int iLigne2 = 0;
    CString sItemsM = "";
    CString sItems1 = "";
    CString sItems2 = "";

    int nCount = pListBox->GetCount();

    int nSelCount = pListBox->GetSelCount();
    //http://msdn.microsoft.com/en-us/library/fycfcb17%28v=vs.90%29.aspx
//DEBUT Simple sélection
    if ( nSelCount == LB_ERR )
    //If the list box is a single-selection list box, the return value is LB_ERR (-1).
    {
        int iPos = pListBox->GetCurSel();

        if ( iPos != 0 )
        {
            iLigne1 = iPos - 1;
            iLigne2= iPos;

            pListBox->GetText(iLigne1, sItems1); 
            pListBox->GetText(iLigne2, sItems2);
            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne1, sItems2);
            pListBox->DeleteString(iLigne2 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
        }
        else
        {
            iLigne1 = 0;
            iLigne2= nCount - 1;

            pListBox->GetText(iLigne2, sItems2);

            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne1, sItems2);
            pListBox->DeleteString(iLigne1 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx

            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne2, sItemsM);
            pListBox->DeleteString(iLigne2 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
        }
        return TRUE;
    }
//FIN Simple sélection

//DEBUT Get the indexes of all the selected items in aryListBoxSel
    CArray<int,int> aryListBoxSel;
    aryListBoxSel.SetSize(nSelCount);
    pListBox->GetSelItems(nSelCount, aryListBoxSel.GetData()); 
    AFXDUMP(aryListBoxSel);    // Dump the selection array.
//FIN  Get the indexes of all the selected items in aryListBoxSel

//DEBUT Multi-Sélection
    for(int i = 0; i < nSelCount; i++)
    {
        iPos = aryListBoxSel.GetAt(i);

        if ( iPos != 0 )
        {
            iLigne1 = iPos - 1;
            iLigne2= iPos;

            pListBox->GetText(iLigne1, sItems1); 
            pListBox->GetText(iLigne2, sItems2);
            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne1, sItems2);
            pListBox->DeleteString(iLigne2 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
            if ( iPos == (iLigne0 + 1 ) )
            {
                iLigne0++;
            }
        }
        else
        {
            iLigne0 = 0;
            pListBox->GetText(iLigne0, sItemsM);
        }
    }

    if ( iLigne0 != -1)
    {
        iLigne1 = iLigne0;
        iLigne2= nCount - 1;

        pListBox->GetText(iLigne2, sItems2);

        //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
        pListBox->InsertString(iLigne1, sItems2);
        pListBox->DeleteString(iLigne1 + 1);
        //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx

        //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
        pListBox->InsertString(iLigne2, sItemsM);
        pListBox->DeleteString(iLigne2 + 1);
        //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
    }
//FIN Multi-Sélection

//DEBUT Re-Sélection des items
    for(int i = 0; i < nCount; i++)
    {
        pListBox->SetSel( i, FALSE);
    }
    for(int i = 0; i < nSelCount; i++)
    {
        iPos = aryListBoxSel.GetAt(i);
        if ( iPos != 0 )
        {
            pListBox->SetSel( iPos -1, TRUE);
        }
        else
        {
            pListBox->SetSel( nCount-1, TRUE);
        }
    }
//FIN Re-Sélection des items
    return TRUE;
}

//-----------------------------------------------------------------------
BOOL Func_1::ListBox_DownItem( CListBox* pListBox  )    //down selected items
{
    int iPos = 0;
    int iLigne0 = -1;
    int iLigne1 = 0;
    int iLigne2 = 0;
    CString sItemsM = "";
    CString sItems1 = "";
    CString sItems2 = "";

    int nCount = pListBox->GetCount();

    int nSelCount = pListBox->GetSelCount();
    //http://msdn.microsoft.com/en-us/library/fycfcb17%28v=vs.90%29.aspx
//DEBUT Simple sélection
    if ( nSelCount == LB_ERR )
    //If the list box is a single-selection list box, the return value is LB_ERR (-1).
    {
        int iPos = pListBox->GetCurSel();

        if ( iPos != (nCount - 1) )
        {
            iLigne1 = iPos;
            iLigne2= iPos + 1;

            pListBox->GetText(iLigne1, sItems1); 
            pListBox->GetText(iLigne2, sItems2);
            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne1, sItems2);
            pListBox->DeleteString(iLigne2 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
        }
        else
        {
            iLigne1 = 0;
            iLigne2= nCount - 1;

            pListBox->GetText(iLigne2, sItems2);

            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne1, sItems2);
            pListBox->DeleteString(iLigne1 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx

            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne2, sItemsM);
            pListBox->DeleteString(iLigne2 + 1);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
        }
        return TRUE;
    }
//FIN Simple sélection

//DEBUT Get the indexes of all the selected items in aryListBoxSel
    CArray<int,int> aryListBoxSel;
    aryListBoxSel.SetSize(nSelCount);
    pListBox->GetSelItems(nSelCount, aryListBoxSel.GetData()); 
    AFXDUMP(aryListBoxSel);    // Dump the selection array.
//FIN  Get the indexes of all the selected items in aryListBoxSel

//DEBUT Multi-Sélection
    for(int i = (nSelCount-1); i >=0; i--)
    {
        iPos = aryListBoxSel.GetAt(i);

        if ( iPos != (nCount - 1) )
        {
            iLigne1 = iPos;
            iLigne2= iPos + 1;

            pListBox->GetText(iLigne1, sItems1); 
            pListBox->GetText(iLigne2, sItems2);
            //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
            pListBox->InsertString(iLigne1, sItems2);
            //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
            pListBox->DeleteString(iLigne2 + 1);
            if ( iPos == (iLigne0 - 1) )
            {
                iLigne0--;
            }
        }
        else
        {
            iLigne0 = nCount - 1;
            pListBox->GetText(iLigne0, sItemsM);
        }
    }

    if ( iLigne0 != -1)
    {
        iLigne1 = iLigne0;
        iLigne2 = 0;

        pListBox->GetText(iLigne2, sItems2);

        //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
        pListBox->InsertString(iLigne1, sItems2);
        pListBox->DeleteString(iLigne1 + 1);
        //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx

        //InsertString: http://msdn.microsoft.com/en-us/library/80ay18e5%28v=vs.90%29.aspx
        pListBox->InsertString(iLigne2, sItemsM);
        pListBox->DeleteString(iLigne2 + 1);
        //DeleteString: http://msdn.microsoft.com/en-us/library/466e49kb%28v=vs.90%29.aspx
    }
//FIN Multi-Sélection

//DEBUT Re-Sélection des items
    for(int i = 0; i < nCount; i++)
    {
        pListBox->SetSel( i, FALSE);
    }
    for(int i = (nSelCount-1); i >=0; i--)
    {
        iPos = aryListBoxSel.GetAt(i);
        if ( iPos != (nCount - 1) )
        {
            pListBox->SetSel( iPos + 1, TRUE);
        }
        else
        {
            pListBox->SetSel( 0, TRUE);
        }
    }
//FIN Re-Sélection des items
    return TRUE;
}

//

Demo

The demo shows an example to select items from 1 Listbox to a 2nd one. The up / down enables to sort items on the 2nd Listbox.

The demo includes a modified version of WndResizer from Mizan Rahman's http://www.codeproject.com/KB/dialog/WndResizer.aspx (The original can be used, modification is for hiding/showing controls.)

Points of Interest

Remark: I tested multiple selection parts but not the single selection part.

License

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


Written By
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Rickyd56a18-Jun-23 17:03
Rickyd56a18-Jun-23 17:03 
QuestionOutstanding work and used on MFC iRibbon application Pin
Rickyd56a18-Jun-23 17:02
Rickyd56a18-Jun-23 17:02 
GeneralMy vote of 1 Pin
Aliya Soultanova15-Apr-14 12:18
Aliya Soultanova15-Apr-14 12:18 
QuestionSimilar thing: Promoting and demoting items in a CListCtrl Pin
kanalbrummer21-Oct-13 22:16
kanalbrummer21-Oct-13 22:16 
QuestionDon't forget to update the moved item's data Pin
.dan.g.18-Sep-13 19:13
professional.dan.g.18-Sep-13 19:13 
SuggestionSource code Pin
Michael Haephrati17-Sep-13 11:00
professionalMichael Haephrati17-Sep-13 11:00 
GeneralMy vote of 5 Pin
Michael Haephrati17-Sep-13 10:59
professionalMichael Haephrati17-Sep-13 10:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.