Jump to content

Sorting ListView with images


Recommended Posts

If you make a listview, and assign the different items their own images, then use the ListViewSort UDF by gafrost, the images do not stick with their items.

Any ideas?

(Sorry, I'll have to write up an example script when I get home, I just got called in to work but I wanted to get this posted before I forgot).

Link to comment
Share on other sites

I think this is the correct behaviour for list view /w images. When it first came out, listview support for images, I also had some query's about what I thought wasn't corrent behaviour and found out it was, I posted it in Bug Reports I think, but moved to Support?. Anyway if you can't find a solution I think you will have to delete the items and re-create them.

Edit: Actually I know the reason, I think. The ListViewSort UDF just changes the text of the item. It doesn't delete or recreate any, which means that say you have 2 items, it doesn't swap index 0 /w index 1. It all stays the same ,the text just changes for each item/subitem. That is why the images don't change because the actual list view item doesn't get swapped, the text just gets swapped.

I have created personal Listview sorting UDF's for myself and I find it is quicker to add all the items into an array, clear the list view, and then recreate each item using the array. Of course if you are using images it will all be reset and you will have to set each image again, some how knowing what the image should be, which I am currently working on.

Summing up, unless gafrost changes his UDF from setting the text to listview swapping (somehow) you will have to use a work around.

Edited by Burrup

qq

Link to comment
Share on other sites

I think this is the correct behaviour for list view /w images. When it first came out, listview support for images, I also had some query's about what I thought wasn't corrent behaviour and found out it was, I posted it in Bug Reports I think, but moved to Support?. Anyway if you can't find a solution I think you will have to delete the items and re-create them.

Edit: Actually I know the reason, I think. The ListViewSort UDF just changes the text of the item. It doesn't delete or recreate any, which means that say you have 2 items, it doesn't swap index 0 /w index 1. It all stays the same ,the text just changes for each item/subitem. That is why the images don't change because the actual list view item doesn't get swapped, the text just gets swapped.

I have created personal Listview sorting UDF's for myself and I find it is quicker to add all the items into an array, clear the list view, and then recreate each item using the array. Of course if you are using images it will all be reset and you will have to set each image again, some how knowing what the image should be, which I am currently working on.

Summing up, unless gafrost changes his UDF from setting the text to listview swapping (somehow) you will have to use a work around.

<{POST_SNAPBACK}>

You right Burrup.

That's the reason why I did'nt enter is this sorting thing. I am sure gafrost can do something.

Remember that's the controlid return at the creation time before sorting will not refer to the same item after sorting.

That's a pity is not basic with windows API

Link to comment
Share on other sites

Have some ideas on how to handle the images, but don't have time to try them out currently, on my way out of town.

@Saunders, if you get time post some code with images if you would, when I get back I'll see what can be done.

Thanks,

Gary

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

No rush, Gary. Thanks for looking into this.

CODE
#include <GuiConstants.au3>

#include <GuiListView.au3>

GuiCreate('ListView Test', 300, 300)

$listview = GuiCtrlCreateListView('Icon Index|Icon Name|Icon File', 0, 0, 300, 300)

GuiCtrlCreateListViewItem('3|Folder|shell32.dll', $listview)

GuiCtrlSetImage(-1, @SystemDir & '\shell32.dll', 3)

GuiCtrlCreateListViewItem('4|Open Folder|shell32.dll', $listview)

GuiCtrlSetImage(-1, @SystemDir & '\shell32.dll', 4)

GuiCtrlCreateListViewItem('8|Fixed Drive|shell32.dll', $listview)

GuiCtrlSetImage(-1, @SystemDir & '\shell32.dll', 8)

GuiCtrlCreateListViewItem('15|My Computer|shell32.dll', $listview)

GuiCtrlSetImage(-1, @SystemDir & '\shell32.dll', 15)

GuiCtrlCreateListViewItem('23|Help|shell32.dll', $listview)

GuiCtrlSetImage(-1, @SystemDir & '\shell32.dll', 23)

GuiCtrlCreateListViewItem('3|Desktop|explorer.exe', $listview)

GuiCtrlSetImage(-1, @WindowsDir & '\explorer.exe', 3)

GuiCtrlCreateListViewItem('2|Printer|explorer.exe', $listview)

GuiCtrlSetImage(-1, @WindowsDir & '\explorer.exe', 2)

GuiCtrlCreateListViewItem('6|Recycle Bin|explorer.exe', $listview)

GuiCtrlSetImage(-1, @WindowsDir & '\explorer.exe', 6)

GuiCtrlCreateListViewItem('5|Taskbar/Start menu|explorer.exe', $listview)

GuiCtrlSetImage(-1, @WindowsDir & '\explorer.exe', 5)

GuiCtrlCreateListViewItem('14|Globe|explorer.exe', $listview)

GuiCtrlSetImage(-1, @WindowsDir & '\explorer.exe', 14)

GuiSetState()

Dim $B_DESCENDING[_GUICtrlListViewGetSubItemsCount ($listview) ]

While 1

$gm = GuiGetMsg()

Select

Case $gm = $listview

_GUICtrlListViewSort($listview, $B_DESCENDING, GUICtrlGetState($listview))

Case $gm = $GUI_EVENT_CLOSE

ExitLoop

EndSelect

WEnd

Link to comment
Share on other sites

I think this is the correct behaviour for list view /w images. When it first came out, listview support for images, I also had some query's about what I thought wasn't corrent behaviour and found out it was, I posted it in Bug Reports I think, but moved to Support?. Anyway if you can't find a solution I think you will have to delete the items and re-create them.

Edit: Actually I know the reason, I think. The ListViewSort UDF just changes the text of the item. It doesn't delete or recreate any, which means that say you have 2 items, it doesn't swap index 0 /w index 1. It all stays the same ,the text just changes for each item/subitem. That is why the images don't change because the actual list view item doesn't get swapped, the text just gets swapped.

I have created personal Listview sorting UDF's for myself and I find it is quicker to add all the items into an array, clear the list view, and then recreate each item using the array. Of course if you are using images it will all be reset and you will have to set each image again, some how knowing what the image should be, which I am currently working on.

Summing up, unless gafrost changes his UDF from setting the text to listview swapping (somehow) you will have to use a work around.

<{POST_SNAPBACK}>

Changed UDF:

_GUICtrlListViewDeleteAllItems

_GUICtrlListViewDeleteItem

The above now use the AutoIt GuiCtrlDelete so items are truly deleted and resource freed

_GUICtrlListViewSort

Now uses _GUICtrlListViewDeleteAllItems and creates new items

Edit: uses GUICtrlCreateListViewItem to create the items

Will submit, haven't had time to look into the images stuff, found problem with latest 2 betas.

Gary

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

1st attempt, has some flicker off to the right end of the listview

Edit: column header to right flickers only now.

any improvements would be gladely accepted.

#include <GuiConstants.au3>
#include <GuiListView.au3>

GUICreate('ListView Test', 300, 300)
$listview = GUICtrlCreateListView('Icon Index|Icon Name|Icon File| | ', 0, 0, 300, 300)
GUICtrlCreateListViewItem('3|Folder|shell32.dll|' & @SystemDir & '\shell32.dll|' & 3, $listview)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 3)
GUICtrlCreateListViewItem('4|Open Folder|shell32.dll|' & @SystemDir & '\shell32.dll|' & 4, $listview)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 4)
GUICtrlCreateListViewItem('8|Fixed Drive|shell32.dll|' & @SystemDir & '\shell32.dll|' & 8, $listview)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 8)
GUICtrlCreateListViewItem('15|My Computer|shell32.dll|' & @SystemDir & '\shell32.dll|' & 15, $listview)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 15)
GUICtrlCreateListViewItem('23|Help|shell32.dll|' & @SystemDir & '\shell32.dll|' & 23, $listview)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 23)
GUICtrlCreateListViewItem('3|Desktop|explorer.exe|' & @WindowsDir & '\explorer.exe|' & 3, $listview)
GUICtrlSetImage(-1, @WindowsDir & '\explorer.exe', 3)
GUICtrlCreateListViewItem('2|Printer|explorer.exe|' & @WindowsDir & '\explorer.exe|' & 2, $listview)
GUICtrlSetImage(-1, @WindowsDir & '\explorer.exe', 2)
GUICtrlCreateListViewItem('6|Recycle Bin|explorer.exe|' & @WindowsDir & '\explorer.exe|' & 6, $listview)
GUICtrlSetImage(-1, @WindowsDir & '\explorer.exe', 6)
GUICtrlCreateListViewItem('5|Taskbar/Start menu|explorer.exe|' & @WindowsDir & '\explorer.exe|' & 5, $listview)
GUICtrlSetImage(-1, @WindowsDir & '\explorer.exe', 5)
GUICtrlCreateListViewItem('14|Globe|explorer.exe|' & @WindowsDir & '\explorer.exe|' & 14, $listview)
GUICtrlSetImage(-1, @WindowsDir & '\explorer.exe', 14)
GUISetState()
_GUICtrlListViewHideColumn ($listview, 3)
_GUICtrlListViewHideColumn ($listview, 4)
Dim $B_DESCENDING[_GUICtrlListViewGetSubItemsCount ($listview) ]
While 1
    $gm = GUIGetMsg()
    Select
        Case $gm = $listview
            _GUICtrlListViewSortWI($listview, $B_DESCENDING, GUICtrlGetState($listview))
        Case $gm = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
WEnd

;===============================================================================
;
; Description:            _GUICtrlListViewSortWI
; Parameter(s):        $h_listview - controlID
;                       $v_descending    - boolean value, can be a single value or array
;                       $i_sortcol        - column to sort on
;                       $s_Title            - Optional: Window title
;                       $s_Text            - Optional: Window text
; Requirement:            Array.au3
; Return Value(s):    None
; User CallTip:        _GUICtrlListViewSortWI(ByRef $h_listview, ByRef $v_descending, $i_sortcol[, $s_Title = ""[, $s_Text = ""]]) Sorts a list-view control (required: <GuiListView.au3>)
; Author(s):            Gary Frost (custompcs@charter.net)
; Note(s):                WI = With Images
;                    Last 2 columns hold the file and index of image
;                    Last 2 columns are hidden
;
;===============================================================================
Func _GUICtrlListViewSortWI(ByRef $h_listview, ByRef $v_descending, $i_sortcol, $s_Title = "", $s_text = "")
    Local $X, $Y, $b_desc, $columns, $items, $v_item, $temp_item
    If (StringLen($s_Title) == 0) Then
        $s_Title = WinGetTitle("")
    EndIf
    If (IsArray($v_descending)) Then
        $b_desc = $v_descending[$i_sortcol]
    Else
        $b_desc = $v_descending
    EndIf
    $columns = _GUICtrlListViewGetSubItemsCount ($h_listview, $s_Title, $s_text)
    $items = _GUICtrlListViewGetItemCount ($h_listview)
    For $X = 1 To $columns
        $temp_item = $temp_item & " |"
    Next
    $temp_item = StringTrimRight($temp_item, 1)
    Local $a_lv[$items][$columns]
    For $X = 0 To UBound($a_lv) - 1 Step 1
        For $Y = 0 To UBound($a_lv, 2) - 1 Step 1
            $v_item = _GUICtrlListViewGetItemText ($h_listview, $X, $Y, $s_Title, $s_text)
            If (StringIsFloat($v_item) Or StringIsInt($v_item)) Then
                $a_lv[$X][$Y] = Number($v_item)
            Else
                $a_lv[$X][$Y] = $v_item
            EndIf
        Next
    Next
    _GUICtrlListViewDeleteAllItems ($h_listview)
    _ArraySort($a_lv, $b_desc, 0, 0, $columns, $i_sortcol)
    For $X = 0 To UBound($a_lv) - 1 Step 1
        GUICtrlCreateListViewItem($temp_item, $h_listview)
        GUICtrlSetImage(-1, $a_lv[$X][UBound($a_lv, 2) - 2], $a_lv[$X][UBound($a_lv, 2) - 1])
    Next
    _GUICtrlListViewHideColumn ($h_listview, $columns - 2)
    _GUICtrlListViewHideColumn ($h_listview, $columns - 1)
    For $X = 0 To UBound($a_lv) - 1 Step 1
        For $Y = 0 To UBound($a_lv, 2) - 1 Step 1
            _GUICtrlListViewSetItemText ($h_listview, $X, $Y, $a_lv[$X][$Y])
        Next
    Next
    If (IsArray($v_descending)) Then
        $v_descending[$i_sortcol] = Not $b_desc
    Else
        $v_descending = Not $b_desc
    EndIf
EndFunc  ;==>_GUICtrlListViewSortWI
Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Do you have a copy of .50, I can't test because I can only go back as far as .51.

@Saunders

I don't have the script any more but if my memory serves me correctly there was a substantial speed difference, I tested it on my current project. The list view columns are years, file sizes, file names, mp3 tag info etc. But then again I compared my own list view sorting UDF's (which delete/recreate the item) to the current 'text swapping' UDF by gafrost.

Try and see a difference with gafrosts above possible new UDF compared to the old one.

Edited by Burrup

qq

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...