Click here to Skip to main content
Click here to Skip to main content

Moving Listbox Items Up and Down

, 13 Oct 2013
Rate this:
Please Sign up or sign in to vote.
For single or multiple selection CListBox

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:

Function_1D.h and Function_1D.cpp 

Example of use:

//----------------------------------------------------------------------------
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:

//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)

Share

About the Author

MaxMax14

France France
No Biography provided

Comments and Discussions

 
GeneralMy vote of 1 PinmemberAliya Soultanova15-Apr-14 12:18 
QuestionSimilar thing: Promoting and demoting items in a CListCtrl Pinmemberkanalbrummer21-Oct-13 22:16 
QuestionDon't forget to update the moved item's data Pinmember.dan.g.18-Sep-13 19:13 
SuggestionSource code PinmvpMichael Haephrati17-Sep-13 11:00 
GeneralMy vote of 5 PinmvpMichael Haephrati17-Sep-13 10:59 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140821.2 | Last Updated 14 Oct 2013
Article Copyright 2013 by MaxMax14
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid