Jump to content

Listview sort with checkboxes


Recommended Posts

Can some one point me in the right direction - When I sort a listview with checkboxes, the text for the rows are resorted correctly. However, the checkboxes do not stay with each appropriate/original row after sort.

What's the most efficient way of resolving this issue. I could have the checkbox info saved in a file and load it each time, but that's cumbersome and not totally what I'm looking for.

A decision is a powerful thing
Link to comment
Share on other sites

Can some one point me in the right direction - When I sort a listview with checkboxes, the text for the rows are resorted correctly. However, the checkboxes do not stay with each appropriate/original row after sort.

What's the most efficient way of resolving this issue. I could have the checkbox info saved in a file and load it each time, but that's cumbersome and not totally what I'm looking for.

Can you post a small example that shows this?
Auto3Lib: A library of over 1200 functions for AutoIt
Link to comment
Share on other sites

#include <GUIConstants.au3>
#include <Constants.au3>
#include <GuiListView.au3>
Opt("TrayIconDebug", 1)
Opt("WinSearchChildren", 1)
TrayTip("AutoIt Script", @ScriptName, 60, 1)

Opt('GuiOnEventMode', 1)

$ParentWin = GUICreate("AutoIt Scheduler", 500, 637, 193, 115)

$ListView1 = GUICtrlCreateListView("Name|StartTime", 24, 80, 445, 417,$LVS_SHOWSELALWAYS);BitOR($LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))
GUICtrlSendMsg($ListView1, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlSendMsg($ListView1, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_CHECKBOXES, $LVS_EX_CHECKBOXES)
GUICtrlCreateListViewItem("PullDate|13:00:00", $ListView1)
GUICtrlCreateListViewItem("Generate|19:00:00", $ListView1)
GUICtrlCreateListViewItem("OverBecome|20:00:00", $ListView1)
_GUICtrlListViewSetCheckState($ListView1, -1, 1)
_GUICtrlListViewSetColumnWidth($ListView1, 0, 300)
_GUICtrlListViewSetColumnWidth($ListView1, 1, 140)

GUISetOnEvent($GUI_EVENT_CLOSE, 'quit', $ParentWin)

GUICtrlSetOnEvent($ListView1, 'sortList')


GUISetState(@SW_SHOW, $ParentWin)

Global $sort_DESCENDING[_GUICtrlListViewGetSubItemsCount($ListView1) ]
Global $sort_ascending = 0

While 1
    Sleep(10)
WEnd

Func sortList()
    _GUICtrlListViewSort($ListView1, $sort_DESCENDING, GUICtrlGetState($ListView1))
    _GUICtrlListViewSetItemSelState($ListView1, 0, 1, 1)
EndFunc   ;==>sortList

Func quit()
    Exit
EndFunc

A decision is a powerful thing
Link to comment
Share on other sites

#include <GUIConstants.au3>
#include <Constants.au3>
#include <GuiListView.au3>
Opt("TrayIconDebug", 1)
Opt("WinSearchChildren", 1)
TrayTip("AutoIt Script", @ScriptName, 60, 1)

Opt('GuiOnEventMode', 1)

$ParentWin = GUICreate("AutoIt Scheduler", 500, 637, 193, 115)

$ListView1 = GUICtrlCreateListView("Name|StartTime", 24, 80, 445, 417,$LVS_SHOWSELALWAYS);BitOR($LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))
GUICtrlSendMsg($ListView1, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlSendMsg($ListView1, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_CHECKBOXES, $LVS_EX_CHECKBOXES)
GUICtrlCreateListViewItem("PullDate|13:00:00", $ListView1)
GUICtrlCreateListViewItem("Generate|19:00:00", $ListView1)
GUICtrlCreateListViewItem("OverBecome|20:00:00", $ListView1)
_GUICtrlListViewSetCheckState($ListView1, -1, 1)
_GUICtrlListViewSetColumnWidth($ListView1, 0, 300)
_GUICtrlListViewSetColumnWidth($ListView1, 1, 140)

GUISetOnEvent($GUI_EVENT_CLOSE, 'quit', $ParentWin)

GUICtrlSetOnEvent($ListView1, 'sortList')
GUISetState(@SW_SHOW, $ParentWin)

Global $sort_DESCENDING[_GUICtrlListViewGetSubItemsCount($ListView1) ]
Global $sort_ascending = 0

While 1
    Sleep(10)
WEnd

Func sortList()
    _GUICtrlListViewSort($ListView1, $sort_DESCENDING, GUICtrlGetState($ListView1))
    _GUICtrlListViewSetItemSelState($ListView1, 0, 1, 1)
EndFunc   ;==>sortList

Func quit()
    Exit
EndFunc
It appears to be a bug in the _GUICtrlListViewSort UDF. It doesn't preserve the checked state of the item during the sort. You'll probably want to post something in the Bug Report forum on this so that it gets fixed. In the mean time, you'll have to implement a work around to save the item and it's checked state and restore the checked state after the sort.
Auto3Lib: A library of over 1200 functions for AutoIt
Link to comment
Share on other sites

Check this out from gafrost. It's some crazy voodoo... pretty sure a goat died to make this:

;gafrost

#include <GUIConstants.au3>


;Global Const $LVFI_PARAM = 0x0001
;Global Const $LVIF_TEXT = 0x0001
;Global Const $LVM_FIRST = 0x1000
Global Const $LVM_GETITEM = $LVM_FIRST + 5
;Global Const $LVM_FINDITEM = $LVM_FIRST + 13
;Global Const $LVM_SETSELECTEDCOLUMN = $LVM_FIRST + 140

Dim $nCurCol = -1
Dim $nSortDir = 1
Dim $bSet = 0
Dim $nCol = -1

$gui = GUICreate("TEST APP!")
$listview = GUICtrlCreateListView("Column 1|Column 2|Column3", 0, 50, 500, 400, $WS_VSCROLL, $LVS_EX_CHECKBOXES + $LVS_EX_GRIDLINES)
GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback
GUICtrlCreateListViewItem("444|444|444", $listview)
GUICtrlCreateListViewItem("333|333|333", $listview)
GUICtrlCreateListViewItem("222|222|222", $listview)
GUICtrlCreateListViewItem("111|111|111", $listview)
GUISetState(@SW_SHOW, $gui)

While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $listview
            $bSet = 0
            $nCurCol = $nCol
            GUICtrlSendMsg($listview, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($listview), 0)
            DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($listview), "int", 0, "int", 1)
    EndSelect
WEnd

; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    Local $nSort
   
    ; Switch the sorting direction
    If $nColumn = $nCurCol Then
        If Not $bSet Then
            $nSortDir = $nSortDir * - 1
            $bSet = 1
        EndIf
    Else
        $nSortDir = 1
    EndIf
    $nCol = $nColumn
    $val1 = GetSubItemText($listview, $nItem1, $nColumn)
    $val2 = GetSubItemText($listview, $nItem2, $nColumn)
   
    $nResult = 0        ; No change of item1 and item2 positions
   
    If $val1 < $val2 Then
        $nResult = -1   ; Put item2 before item1
    ElseIf $val1 > $val2 Then
        $nResult = 1    ; Put item2 behind item1
    EndIf
   
    $nResult = $nResult * $nSortDir
   
    Return $nResult
EndFunc   ;==>LVSort

; Retrieve the text of a listview item in a specified column
Func GetSubItemText($nCtrlID, $nItemID, $nColumn)
    Local $stLvfi = DllStructCreate("uint;ptr;int;int[2];int")
    DllStructSetData($stLvfi, 1, $LVFI_PARAM)
    DllStructSetData($stLvfi, 3, $nItemID)
   
    Local $stBuffer = DllStructCreate("char[260]")
   
    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi));
   
    Local $stLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")
   
    DllStructSetData($stLvi, 1, $LVIF_TEXT)
    DllStructSetData($stLvi, 2, $nIndex)
    DllStructSetData($stLvi, 3, $nColumn)
    DllStructSetData($stLvi, 6, DllStructGetPtr($stBuffer))
    DllStructSetData($stLvi, 7, 260)
   
    GUICtrlSendMsg($nCtrlID, $LVM_GETITEM, 0, DllStructGetPtr($stLvi));
   
    $sItemText = DllStructGetData($stBuffer, 1)
   
    $stLvi = 0
    $stLvfi = 0
    $stBuffer = 0
   
    Return $sItemText
EndFunc   ;==>GetSubItemText
Edited by xcal
Link to comment
Share on other sites

xcal, wow! Gafrost certainly knows his stuff and posts great 'example files' !! How'd you find that?

Thanks again.

PaulIA, thanks so much for the explanation and note to report as bug.

What should I name the bug report thread?

A decision is a powerful thing
Link to comment
Share on other sites

Just did a search for...

+listview +sort +checkbox

...and checked 'search titles only.'

:whistle: I feel like a dork. I didn't realize that I could use the standard + to string a search like that. I'm a dork. Thanks so much! That will WAY help my searching!!! sheesh it really will.

Edited by JohnBailey
A decision is a powerful thing
Link to comment
Share on other sites

  • 4 weeks later...

I'm pulling my hair out (well nearly smile.gif ) . I've been researching and experimenting (educated guesses), but I can't figure out how to initiate a sort with LVSort on start. Basically, I want the script to sort using that method described in the help manual for GUICtrlRegisterListViewSort when it starts and also when it finishes different processes. I'm not asking for you to write the script (because I don't want you to). I want to learn this, but I'm stuck!

Func sort()
         $nSortDir = -1
     $bSet = 1
        $nCurCol = $nCol
    LVSort(3, 14, 15, 0)
        GUICtrlSendMsg($ListView1, 4236, GUICtrlGetState($ListView1), 0)
    DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($ListView1), "int", 0, "int", 1)
EndFunc

The problem is I don't really know what is being said with everything. For instance, I know the first parameter of LVSort ($hWnd) is the winhandler pertaining to the listview, but I don't know for sure what the other three pars are for LVSort. Yes, I did read the manual and researched the terms so I can have a working base, but I don't know what the parameters all mean for sure.

I'm guessing $nCurCol or $nCol is the key. I have it sorting but I can't get it to sort descending.

Thanks for any more nudges you can give me (without giving it away) !

Edited by JohnBailey
A decision is a powerful thing
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...