In Listview Items verschieben mit mitwandernder Markierung

  • Mein Problem ist zwei Vorgänge gleichzeitig zu skripten. In einer Listview sollen ein oder mehrere Elemente nach oben oder nach unten um 1 verschoben werden und die Markierung beibehalten werden. Element3, Element6 sollen bei 1 nach oben an 2. und 5.Stelle und gleichzeitig die Markierung (Unterlegeung mit Blau) beibehalten. Verschieben klappt, aber die blaue Markierung bleibt an der alten Position "kleben". Hab leider nichts im Archiv gefunden und mein Skript ist so lang, dass das eigentliche Problem darin untergeht und die meisten wegen Länge wohl abschreckt, aber vielleicht gab es dieses Thema schon irgendwo einmal. Gruss Jan

    • Offizieller Beitrag

    So ohne Code schwierig.
    Also:
    - MultiseleKtion Element 3 und 6
    - Element 3 soll Element 2 werden (wohin soll 2 ?)
    - Element 6 soll Element 5 werden (wohin soll 5 ?)
    - beide Elemente sollen an neuer Position markiert sein

    Ist das korrekt?

    EDIT:

    Hab dir mal 'ne Lösung gemacht. Die 'verdrängten' Elemente wandern einen Platz hoch.
    Eine Multiselektion per Skript habe ich nicht hinbekommen. Blau sowieso nicht, maximal läßt sich der zuletzt verschobene Eintrag grau markieren.

    Hab dafür eine neue Funktion erstellt ( _MoveLVItem), die sicher auch für andere interessant sein könnte. Stell ich mal noch in die Skripte.

    Spoiler anzeigen
    [autoit]

    #Include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func AForm1Close()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Button1Click()
    Local $arSelItems = _GUICtrlListViewGetSelectedIndices($ListView1, 1)
    Local $skip = -1 ; wie weit und in welche Richtung verschieben
    For $i = 1 To $arSelItems[0]
    _MoveLVItem($arSelItems[$i], $skip, $ListView1)
    ;~ _GUICtrlListViewSetItemSelState($ListView1, $arSelItems[$i]+$skip) ; markiert nur letzten Wert
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    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)
    Local $txtFromTarget = _GUICtrlListViewGetItemText($hLV, $ItemIndex + $StepWidth)
    _GUICtrlListViewInsertItem($hLV, $ItemIndex + $StepWidth, $txt2skip)
    _GUICtrlListViewDeleteItem($hLV, $ItemIndex+1)
    Return -1
    EndFunc

    [/autoit]
  • Hi,
    Dein Script muss ich noch studieren, da ich dieses Skript mittlerweile verfasste, dass das Problem gut beleuchtet d.h. Der Inhalt einer listviw wandert nach oben oder unten. Es gelingt mir aber nicht, die Markierung mitwandern zu lassen. Weder so noch so .Herzlichst Jan

    S k r i p t ü b e r a r b e i t e t
    ===================

    [autoit]

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

    [/autoit][autoit][/autoit][autoit]

    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)

    [/autoit][autoit][/autoit][autoit]

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

    [/autoit][autoit][/autoit][autoit]

    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

    [/autoit][autoit][/autoit][autoit]

    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.

    [/autoit][autoit][/autoit][autoit]

    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

    [/autoit]

    2 Mal editiert, zuletzt von janrenzlow (13. August 2007 um 15:01)

  • Hallo Bugfix,
    habe Dein Skript getest. Das Verschieben von Items in einer Listview gelingt Dir wie mir. Nur das Markieren (Blau hinterlegen) nicht. Irgendwas flackert bei Dir auf und ist augenblicklich weg.

    Noch einmal. Item 2 und Item5 sollen um 1 aufrutschen und die blaue Markierung auch nach der Verschiebung beibehalten. Item2 müsste auf dem neuen Platz1 und Item5 auf dem neuen Platz 4 noch immer blau markiert sein. Gruss Jan

    Einmal editiert, zuletzt von janrenzlow (13. August 2007 um 14:35)

    • Offizieller Beitrag

    Hipp-Hipp-Hurra ;) - gelöst.

    Ist vielleicht nicht die elegantetse Methode, aber es funktioniert. Ich simuliere nur per Send(), wie ich es sonst per Hand getan hätte.
    In der Funktion " Button1Click()" wird das erledigt.

    Spoiler anzeigen
    [autoit]

    #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("Spalte1|Spalte2|Spalte3", 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('Zeile ' & $i & '- 1' & '| - 2 | - 3', $ListView1)
    Next
    $Button1 = GUICtrlCreateButton("Move With Selection", 388, 340, 121, 29, 0)
    GUICtrlSetOnEvent(-1, "Button1Click")
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func AForm1Close()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Button1Click()
    Local $arSelItems = _GUICtrlListViewGetSelectedIndices($ListView1, 1)
    Local $skip = -1 ; wie weit und in welche Richtung verschieben
    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 & "}") ; Auf Listenanfang
    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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;----------------------------------------------------------------------------------------------------------------------
    ; Funktion _MoveLVItem($ItemIndex, $StepWidth, $hLV)
    ;
    ; Beschreibung verschiebt per Index angegebenen Eintrag eines ListViewCtrl um eine Anzahl Positionen
    ;
    ; Parameter $ItemIndex: Index der Zeile
    ; $StepWidth: Anzahl Zeilen um die der Eintrag verschoben wird (negative Zahl - aufwärts)
    ; $hLV: ListView ID
    ;
    ; Erfordernisse #include <GuiListView.au3>
    ;
    ; Autor BugFix ([email='bugfix@autoit.de'][/email])
    ;----------------------------------------------------------------------------------------------------------------------
    #include <GuiListView.au3>
    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

    [/autoit]