locked
how can a listview's header show a triangle when i sort items RRS feed

  • Question

  • hi,

    I have window with ListView control. The ListView control has few
    columns which user can sort by clicking the column header.

    I want the column header have the small triangle indicator of sort order.
    How can I implement that?

    Thanks

    Tuesday, August 24, 2010 4:04 AM

Answers

  • I have window with ListView control. The ListView control has few
    columns which user can sort by clicking the column header.

    I want the column header have the small triangle indicator of sort order.
    How can I implement that?

    I don't know if there's a built in method, but I did this years ago.
    This is just fragments of code from a project - so just treat it as
    hints of how it can be done!

    Initialisation...

        * Create an image list for the sort icons for the list's
    header control *

        {
            * Initialise the image list for the sort icons *
            m_SortIcons.Create( 8, 8, ILC_MASK, 2, 2 );
            HICON hIco1;
            hIco1 = static_cast<HICON>( LoadImage(
    AfxGetInstanceHandle(), MAKEINTRESOURCE( IDI_UP ), IMAGE_ICON, 0, 0,
    LR_DEFAULTCOLOR ) );
            m_SortIcons.Add( hIco1 );
            hIco1 = static_cast<HICON>( LoadImage(
    AfxGetInstanceHandle(), MAKEINTRESOURCE( IDI_DOWN ), IMAGE_ICON, 0, 0,
    LR_DEFAULTCOLOR ) );
            m_SortIcons.Add( hIco1 );

            m_List.GetHeaderCtrl()->SetImageList( &m_SortIcons );
        }

    Removing the sort indicator...

        * Remove the existing sort indicator from the list's header
    control *

        HDITEM hdi;
        CHeaderCtrl * pHeader = m_List.GetHeaderCtrl();

        if ( m_SortCol != -1 )
        {
            * Remove the existing sort indicator *
            hdi.mask= HDI_FORMAT;
            hdi.fmt= HDF_LEFT | HDF_STRING;
            pHeader->SetItem( m_SortCol, &hdi );
        }

    Setting the sort indicator...
        * Set the sort indicator in the list's header control *
        hdi.mask= HDI_IMAGE | HDI_FORMAT;

        if ( m_bAscending )
        {
            hdi.iImage= 0;    // Ascending
        }
        else
        {
            hdi.iImage= 1;    // Descending
        }

        hdi.fmt= HDF_LEFT | HDF_IMAGE | HDF_STRING |
    HDF_BITMAP_ON_RIGHT;
        pHeader->SetItem( col, &hdi );

    Dave

    • Proposed as answer by Jesse Jiang Thursday, August 26, 2010 9:15 AM
    • Marked as answer by LeoGaGa Thursday, August 26, 2010 9:26 AM
    Tuesday, August 24, 2010 8:23 AM
  • Hi Jesse,

    the code has been showed as below:

       HD_ITEM hditem = {0};

      hditem.mask = HDI_FORMAT | HDI_BITMAP;
      HWND hHdr = ListView_GetHeader(_listView);
      ::SendMessage(hHdr, HDM_GETITEM, iIndex, (LPARAM)&hditem);  //iIndex represent the index of column be clicked

      hditem.fmt &= ~(HDF_BITMAP | HDF_BITMAP_ON_RIGHT);


       hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT;  
       if(_ascending)  //_ascending sort
        hditem.hbm = LoadBitmap(GetModuleHandleA(NULL), MAKEINTRESOURCE(IDB_ITEM_IMAGE_UP));
       else
        hditem.hbm = LoadBitmap(GetModuleHandleA(NULL), MAKEINTRESOURCE(IDB_ITEM_IMAGE_DOWN));

        ::SendMessage(hHdr, HDM_SETITEM, iIndex, (LPARAM)&hditem);

    Kindest regards

    Leo

     

    • Marked as answer by Jesse Jiang Friday, August 27, 2010 9:11 AM
    Thursday, August 26, 2010 9:25 AM

All replies

  • I have window with ListView control. The ListView control has few
    columns which user can sort by clicking the column header.

    I want the column header have the small triangle indicator of sort order.
    How can I implement that?

    I don't know if there's a built in method, but I did this years ago.
    This is just fragments of code from a project - so just treat it as
    hints of how it can be done!

    Initialisation...

        * Create an image list for the sort icons for the list's
    header control *

        {
            * Initialise the image list for the sort icons *
            m_SortIcons.Create( 8, 8, ILC_MASK, 2, 2 );
            HICON hIco1;
            hIco1 = static_cast<HICON>( LoadImage(
    AfxGetInstanceHandle(), MAKEINTRESOURCE( IDI_UP ), IMAGE_ICON, 0, 0,
    LR_DEFAULTCOLOR ) );
            m_SortIcons.Add( hIco1 );
            hIco1 = static_cast<HICON>( LoadImage(
    AfxGetInstanceHandle(), MAKEINTRESOURCE( IDI_DOWN ), IMAGE_ICON, 0, 0,
    LR_DEFAULTCOLOR ) );
            m_SortIcons.Add( hIco1 );

            m_List.GetHeaderCtrl()->SetImageList( &m_SortIcons );
        }

    Removing the sort indicator...

        * Remove the existing sort indicator from the list's header
    control *

        HDITEM hdi;
        CHeaderCtrl * pHeader = m_List.GetHeaderCtrl();

        if ( m_SortCol != -1 )
        {
            * Remove the existing sort indicator *
            hdi.mask= HDI_FORMAT;
            hdi.fmt= HDF_LEFT | HDF_STRING;
            pHeader->SetItem( m_SortCol, &hdi );
        }

    Setting the sort indicator...
        * Set the sort indicator in the list's header control *
        hdi.mask= HDI_IMAGE | HDI_FORMAT;

        if ( m_bAscending )
        {
            hdi.iImage= 0;    // Ascending
        }
        else
        {
            hdi.iImage= 1;    // Descending
        }

        hdi.fmt= HDF_LEFT | HDF_IMAGE | HDF_STRING |
    HDF_BITMAP_ON_RIGHT;
        pHeader->SetItem( col, &hdi );

    Dave

    • Proposed as answer by Jesse Jiang Thursday, August 26, 2010 9:15 AM
    • Marked as answer by LeoGaGa Thursday, August 26, 2010 9:26 AM
    Tuesday, August 24, 2010 8:23 AM
  • hi dave,

    thanks for your code.i have solved this problem yesterday.Your code base on MFC,my App base on Win32,so i need transform your code to code i can use,i didn't do this.

    leo

    Wednesday, August 25, 2010 1:41 AM
  •  

    Hi LeoGaGa,

     

    I shall be pleased will you can share your code of solving this issue.

     

    Have a nice day!

    Jesse


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, August 26, 2010 9:16 AM
  • Hi Jesse,

    the code has been showed as below:

       HD_ITEM hditem = {0};

      hditem.mask = HDI_FORMAT | HDI_BITMAP;
      HWND hHdr = ListView_GetHeader(_listView);
      ::SendMessage(hHdr, HDM_GETITEM, iIndex, (LPARAM)&hditem);  //iIndex represent the index of column be clicked

      hditem.fmt &= ~(HDF_BITMAP | HDF_BITMAP_ON_RIGHT);


       hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT;  
       if(_ascending)  //_ascending sort
        hditem.hbm = LoadBitmap(GetModuleHandleA(NULL), MAKEINTRESOURCE(IDB_ITEM_IMAGE_UP));
       else
        hditem.hbm = LoadBitmap(GetModuleHandleA(NULL), MAKEINTRESOURCE(IDB_ITEM_IMAGE_DOWN));

        ::SendMessage(hHdr, HDM_SETITEM, iIndex, (LPARAM)&hditem);

    Kindest regards

    Leo

     

    • Marked as answer by Jesse Jiang Friday, August 27, 2010 9:11 AM
    Thursday, August 26, 2010 9:25 AM