Sign in to follow this  
Followers 0
jlorenz1

Problem with multi highlighted rows in listview after update

4 posts in this topic

#1 ·  Posted (edited)

Hi,

In a listview I want to move items up and down and they should keep their Highlightning on their new place. The first thing works well, but not the second. Here is a demo of my problem, which is more a problem of highlightning: Johannes

#include <GuiListView.au3>
#include <array.au3>

Opt ('MustDeclareVars', 1)
Dim $listview, $Btn_MoveUp, $Btn_MoveDown, $Btn_Exit, $msg, $Status, $GUI, $i, $j
Global $avRowCache[1][2], $sHighlightNew =''; Cache vor Rowtxt
$GUI = GUICreate("Move Up/Down and hightlight it", 392, 322)

$listview = GUICtrlCreateListView("col1|col2|col3", 40, 30, 310, 149, BitOR($LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))
GUICtrlCreateListViewItem("line1|data1|more1", $listview)
GUICtrlCreateListViewItem("line2|data2|more2", $listview)
GUICtrlCreateListViewItem("line3|data3|more3", $listview)
GUICtrlCreateListViewItem("line4|data4|more4", $listview)
GUICtrlCreateListViewItem("line5|data5|more5", $listview)
$Btn_MoveUp = GUICtrlCreateButton("Move Up", 75, 200, 90, 40)
$Btn_MoveDown = GUICtrlCreateButton("Move Down", 200, 200, 90, 40)
$Btn_Exit = GUICtrlCreateButton("Exit", 300, 260, 70, 30)
$Status = GUICtrlCreateLabel("", 0, 302, 392, 20, BitOR($SS_SUNKEN, $SS_CENTER))

GUISetState()
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE Or $msg = $Btn_Exit
            ExitLoop
        Case $msg = $Btn_MoveUp
            _MoveUpDown($listview, 0)
        Case $msg = $Btn_MoveDown
            _MoveUpDown($listview, 1)
    EndSelect
WEnd
Exit

Func _MoveUpDown($sLView, $iUpDown)
    Dim $avTxt1, $avTxt2,  $i, $j, $sHighlightNew = '', $iErr = 0, $avSelectRows, $iNextIndex = 0, $avHighlightNew
;$iUpDown = 0 means up, $iUpDown = 1 means down
    If $iUpDown < 0 then $iErr = $iErr + 1
    If $iUpDown < 1 then $iErr = $iErr + 2
    
    $avSelectRows = _GUICtrlListViewGetSelectedIndices($listview, 1)
    For $i = 1 to $avSelectRows[0]
        If $iUpDown == 0 AND $avSelectRows[$i] == 0 then $iErr = $iErr +4; has already the lowest pos.
        If $iUpDown == 1 AND $avSelectRows[$i] ==_GUICtrlListViewGetItemCount ($listview) then $iErr = $iErr +8; has already the hightest pos.

        If $iUpDown == 0 Then $iNextIndex = Number($avSelectRows[$i])-1
        If $iUpDown == 1 Then $iNextIndex = Number($avSelectRows[$i])+1     
        $avTxt1 = StringSplit(_GUICtrlListViewGetItemText($listview, $avSelectRows[$i]), '|')
        $avTxt2 = StringSplit(_GUICtrlListViewGetItemText($listview, $iNextIndex), '|')
        For $j = 0 to $avTxt1[0]-1;cause cero-based, swap contents of both rows
             _GUICtrlListViewSetItemText ($listview, $avSelectRows[$i], $j, $avTxt2[$j +1])
             _GUICtrlListViewSetItemText ($listview, $iNextIndex, $j, $avTxt1[$j +1])
             $sHighlightNew = $sHighlightNew & '|' & $iNextIndex
        Next
    Next
    $avHighlightNew = StringSplit(StringTrimLeft ($sHighlightNew,1),'|')
    For $i = 1 to $avHighlightNew[0]
        _GUICtrlListViewSetItemSelState ($listview, $avHighlightNew[$i])
    Next 
    SetError ($iErr, 0, $iErr)
EndFunc

example2.au3

Edited by jlorenz1

Johannes LorenzBensheim, Germanyjlorenz1@web.de[post="12602"]Highlightning AutoIt Syntax in Notepad++ - Just copy in your Profile/application data/notepad++[/post]

Share this post


Link to post
Share on other sites



May be that a better way exist. But this solution works.

#include <GUIConstants.au3>
#Include <GuiListView.au3>

Opt("GUIOnEventMode", 1)
Dim $arItem[8]
$AForm1 = GUICreate("AForm1", 633, 454, 193, 115)
GUISetOnEvent($GUI_EVENT_CLOSE, "AForm1Close")
$ListView1 = GUICtrlCreateListView("Column1|Column2|Column3", 76, 76, 429, 221, BitOR _
($LVS_REPORT,$LVS_SHOWSELALWAYS), BitOR($WS_EX_CLIENTEDGE,$LVS_EX_GRIDLINES, _
$LVS_EX_FULLROWSELECT))
GUICtrlSendMsg(-1, 0x101E, 0, 80)
GUICtrlSendMsg(-1, 0x101E, 1, 80)
GUICtrlSendMsg(-1, 0x101E, 2, 80)
For $i = 0 To 7
    $arItem[$i] = GUICtrlCreateListViewItem('Row ' & $i & '- 1' & '| - 2 | - 3', $ListView1)
Next
$Button1 = GUICtrlCreateButton("Move With Selection", 388, 340, 121, 29, 0)
GUICtrlSetOnEvent(-1, "Button1Click")
GUISetState(@SW_SHOW)

While 1
    Sleep(100)
WEnd

Func AForm1Close()
    Exit
EndFunc

Func Button1Click()
    Local $arSelItems = _GUICtrlListViewGetSelectedIndices($ListView1, 1)
    Local $skip = -1
    For $i = 1 To $arSelItems[0]
        _MoveLVItem($arSelItems[$i], $skip, $ListView1)
    Next
    GUISetState(@SW_LOCK, $AForm1)
    ControlClick($AForm1, '', $ListView1)
    $idx = _GUICtrlListViewGetSelectedIndices($ListView1, 0)
    Send("{UP " & $idx & "}") 
    For $i = 1 To $arSelItems[0]
        If $i = 1 Then 
            If $arSelItems[$i]+$skip > 0 Then
                Send("{DOWN " & $arSelItems[$i]+$skip & "}")
            EndIf
        Else
            Send("^{DOWN " & $arSelItems[$i]-$arSelItems[$i-1] & "}")
            Send("^{SPACE}")
        EndIf
    Next
    GUISetState(@SW_UNLOCK, $AForm1)
EndFunc


Func _MoveLVItem($ItemIndex, $StepWidth, $hLV)
    If  ($ItemIndex + $StepWidth) < 0 Or _
        ($ItemIndex + $StepWidth) > _GUICtrlListViewGetItemCount($hLV)-1 Then
        SetError(1)
        Return 0
    EndIf
    Local $txt2skip = _GUICtrlListViewGetItemText($hLV, $ItemIndex)
    _GUICtrlListViewInsertItem($hLV, $ItemIndex + $StepWidth, $txt2skip)
    _GUICtrlListViewDeleteItem($hLV, $ItemIndex+1)
    Return -1
EndFunc ;==>_MoveLVItem

Best Regards BugFix  

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

May be that a better way exist. But this solution works.

#include <GUIConstants.au3>
#Include <GuiListView.au3>

Opt("GUIOnEventMode", 1)
Dim $arItem[8]
$AForm1 = GUICreate("AForm1", 633, 454, 193, 115)
GUISetOnEvent($GUI_EVENT_CLOSE, "AForm1Close")
$ListView1 = GUICtrlCreateListView("Column1|Column2|Column3", 76, 76, 429, 221, BitOR _
($LVS_REPORT,$LVS_SHOWSELALWAYS), BitOR($WS_EX_CLIENTEDGE,$LVS_EX_GRIDLINES, _
$LVS_EX_FULLROWSELECT))
GUICtrlSendMsg(-1, 0x101E, 0, 80)
GUICtrlSendMsg(-1, 0x101E, 1, 80)
GUICtrlSendMsg(-1, 0x101E, 2, 80)
For $i = 0 To 7
    $arItem[$i] = GUICtrlCreateListViewItem('Row ' & $i & '- 1' & '| - 2 | - 3', $ListView1)
Next
$Button1 = GUICtrlCreateButton("Move With Selection", 388, 340, 121, 29, 0)
GUICtrlSetOnEvent(-1, "Button1Click")
GUISetState(@SW_SHOW)

While 1
    Sleep(100)
WEnd

Func AForm1Close()
    Exit
EndFunc

Func Button1Click()
    Local $arSelItems = _GUICtrlListViewGetSelectedIndices($ListView1, 1)
    Local $skip = -1
    For $i = 1 To $arSelItems[0]
        _MoveLVItem($arSelItems[$i], $skip, $ListView1)
    Next
    GUISetState(@SW_LOCK, $AForm1)
    ControlClick($AForm1, '', $ListView1)
    $idx = _GUICtrlListViewGetSelectedIndices($ListView1, 0)
    Send("{UP " & $idx & "}") 
    For $i = 1 To $arSelItems[0]
        If $i = 1 Then 
            If $arSelItems[$i]+$skip > 0 Then
                Send("{DOWN " & $arSelItems[$i]+$skip & "}")
            EndIf
        Else
            Send("^{DOWN " & $arSelItems[$i]-$arSelItems[$i-1] & "}")
            Send("^{SPACE}")
        EndIf
    Next
    GUISetState(@SW_UNLOCK, $AForm1)
EndFunc
Func _MoveLVItem($ItemIndex, $StepWidth, $hLV)
    If  ($ItemIndex + $StepWidth) < 0 Or _
        ($ItemIndex + $StepWidth) > _GUICtrlListViewGetItemCount($hLV)-1 Then
        SetError(1)
        Return 0
    EndIf
    Local $txt2skip = _GUICtrlListViewGetItemText($hLV, $ItemIndex)
    _GUICtrlListViewInsertItem($hLV, $ItemIndex + $StepWidth, $txt2skip)
    _GUICtrlListViewDeleteItem($hLV, $ItemIndex+1)
    Return -1
EndFunc ;==>_MoveLVItem
Hi Bugfix,

The send-command is a little dirty trick, but it works. I gave you my thanks also on the german autoit-forum. Perhaps somebody has a better solution without using the send-command? Johannes

Edited by jlorenz1

Johannes LorenzBensheim, Germanyjlorenz1@web.de[post="12602"]Highlightning AutoIt Syntax in Notepad++ - Just copy in your Profile/application data/notepad++[/post]

Share this post


Link to post
Share on other sites

Perhaps somebody has a better solution without using the send-command?

Try this, it uses PaulIA's A3LListView.au3 from his Auto3Lib.

I tried using the standard _GuiCtrlListView UDF but kept getting inconsistent results.

Also, you'll need to clean up the code a bit, and I'm sure there's some redundancy in there that could be stripped out too.

And, I get an array error when using the down button and reaching the bottom of the list.

From SciTE:

temp-41.au3 (57) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

_GUICtrlListViewSetItemText($listview, $avSelectRows[$i], $j, $avTxt2[$j + 1])

_GUICtrlListViewSetItemText($listview, $avSelectRows[$i], $j, ^ ERROR

#include <GuiListView.au3>
#include <array.au3>
#include <A3LListView.au3>

Opt('MustDeclareVars', 1)
Dim $listview, $Btn_MoveUp, $Btn_MoveDown, $Btn_Exit, $msg, $Status, $GUI, $i, $j, $hListView, $LvCount
Global $avRowCache[1][2], $sHighlightNew = ''; Cache vor Rowtxt
$GUI = GUICreate("Move Up/Down and hightlight it", 392, 322)

$listview = GUICtrlCreateListView("col1|col2|col3", 40, 30, 310, 149, BitOR($LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))

GUICtrlCreateListViewItem("line1|data1|more1", $listview)
GUICtrlCreateListViewItem("line2|data2|more2", $listview)
GUICtrlCreateListViewItem("line3|data3|more3", $listview)
GUICtrlCreateListViewItem("line4|data4|more4", $listview)
GUICtrlCreateListViewItem("line5|data5|more5", $listview)
$Btn_MoveUp = GUICtrlCreateButton("Move Up", 75, 200, 90, 40)
$Btn_MoveDown = GUICtrlCreateButton("Move Down", 200, 200, 90, 40)
$Btn_Exit = GUICtrlCreateButton("Exit", 300, 260, 70, 30)
$Status = GUICtrlCreateLabel("", 0, 302, 392, 20, BitOR($SS_SUNKEN, $SS_CENTER))
$hListView = ControlGetHandle($GUI, "", $listview)
$LvCount = _ListView_GetItemCount ($hListView)

Dim $aSelected[$LvCount]

GUISetState()
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE Or $msg = $Btn_Exit
            ExitLoop
        Case $msg = $Btn_MoveUp
            _MoveUpDown($listview, 0)
        Case $msg = $Btn_MoveDown
            _MoveUpDown($listview, 1)
    EndSelect
WEnd
Exit

Func _MoveUpDown($sLView, $iUpDown)
    _GetSelectedItems($aSelected)
    Dim $avTxt1, $avTxt2, $i, $j, $sHighlightNew = '', $iErr = 0, $avSelectRows, $iNextIndex = 0, $avHighlightNew
    ;$iUpDown = 0 means up, $iUpDown = 1 means down
    If $iUpDown < 0 Then $iErr = $iErr + 1
    If $iUpDown < 1 Then $iErr = $iErr + 2

    $avSelectRows = _GUICtrlListViewGetSelectedIndices($listview, 1)
    For $i = 1 To $avSelectRows[0]
        If $iUpDown == 0 And $avSelectRows[$i] == 0 Then $iErr = $iErr + 4; has already the lowest pos.
        If $iUpDown == 1 And $avSelectRows[$i] == _GUICtrlListViewGetItemCount($listview) Then $iErr = $iErr + 8; has already the hightest pos.

        If $iUpDown == 0 Then $iNextIndex = Number($avSelectRows[$i]) - 1
        If $iUpDown == 1 Then $iNextIndex = Number($avSelectRows[$i]) + 1
        $avTxt1 = StringSplit(_GUICtrlListViewGetItemText($listview, $avSelectRows[$i]), '|')
        $avTxt2 = StringSplit(_GUICtrlListViewGetItemText($listview, $iNextIndex), '|')
        For $j = 0 To $avTxt1[0] - 1;cause cero-based, swap contents of both rows
            _GUICtrlListViewSetItemText($listview, $avSelectRows[$i], $j, $avTxt2[$j + 1])
            _GUICtrlListViewSetItemText($listview, $iNextIndex, $j, $avTxt1[$j + 1])
            ;$sHighlightNew = $sHighlightNew & '|' & $iNextIndex
        Next
    Next
    _HighlightNew($aSelected)
    ;$avHighlightNew = StringSplit(StringTrimLeft ($sHighlightNew,1),'|')
    ;For $i = 1 to $avHighlightNew[0]
    ;    _GUICtrlListViewSetItemSelState ($listview, $avHighlightNew[$i])
    ;Next
    SetError($iErr, 0, $iErr)
EndFunc   ;==>_MoveUpDown


Func _GetSelectedItems(ByRef $aSelected)
    For $i = 0 To UBound($aSelected) - 1
        If _ListView_GetItemSelected ($hListView, $i) Then
            $aSelected[$i] = _ListView_GetItemText ($hListView, $i)
        Else
            $aSelected[$i] = ""
        EndIf
    Next
EndFunc   ;==>_GetSelectedItems

Func _HighlightNew(ByRef $aSelected)
    Local $iHighlight
    For $i = 0 To UBound($aSelected) - 1
        _GUICtrlListViewSetItemSelState($hListView, $i, 0); un-highlight all
    Next
    For $i = 0 To UBound($aSelected) - 1
        If $aSelected[$i] <> "" Then
            $iHighlight = _ListView_FindText ($hListView, $aSelected[$i])
            _GUICtrlListViewSetItemSelState($hListView, $iHighlight, 1) ; highlight new position
        EndIf
        $aSelected[$i] = ""

    Next
EndFunc   ;==>_HighlightNew

Share this post


Link to post
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
Sign in to follow this  
Followers 0