In ListBox items/Einträge verschieben

  • Hi alle

    Ist es möglich in einer Listbox items mit einem Button nach oben oder unten zu verschieben?

    Habe bis her nur Bespiele für Listview oder Combobox gefunden.

    Einmal editiert, zuletzt von VinceA (31. Mai 2013 um 10:10)

  • Meines Wissens ist gibt es keinen Befehl zum Verschieben der Elemente.
    Daher muß kann man das Ganze "von Hand" machen 8)
    Einfach- und Mehrfachauswahl ist möglich; Auswahl bleibt nach dem Verschieben erhalten; Verschieben kann sofort wiederholt werden...

    Spoiler anzeigen
    [autoit]

    #include <GuiListBox.au3>
    #include <ListboxConstants.au3>
    #include <WindowsConstants.au3>

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

    Opt("GUIOnEventMode", 1)

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

    $wMain = GUICreate("VerschiebIt mit AutoIt", 300, 300)
    GUISetOnEvent(-3, "_Exit")

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

    $lList = _GUICtrlListBox_Create($wMain, "", 0, 0, 240, 300, $LBS_STANDARD + $LBS_EXTENDEDSEL + $WS_VSCROLL)
    $bBtnUp = GUICtrlCreateButton("Hoch", 245, 110, 50)
    GUICtrlSetOnEvent(-1, "_Move")
    $bBtnDown = GUICtrlCreateButton("Runter", 245, 150, 50)
    GUICtrlSetOnEvent(-1, "_Move")

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

    For $i = 1 To 30
    _GUICtrlListBox_AddString($lList, StringFormat("Zeile Nr. %02s und noch'n bisschen Text dazu", $i));==> StringFormat, damit's hübscher aussieht ;)
    Next

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

    GUISetState()

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

    While 1
    Sleep(5000)
    WEnd

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

    Func _Move()
    $multiSel = _GUICtrlListBox_GetSelItems($lList);==> gibt Array mit den Indizes der ausgewählten Elemente zurück
    If @GUI_CtrlId = $bBtnUp Then
    If $multiSel[1] < 1 Then Return ;==> wenn die oberste Auswahl den Anfang der Liste erreicht hat
    $first = 1
    $last = $multiSel[0] ;==> $multiSel[0] enthält die Anzahl der ausgewählen Elemente
    $step = -1
    Else
    If $multiSel[$multiSel[0]] = _GUICtrlListBox_GetCount($lList) - 1 Then Return ;==> wenn die unterste Auswahl das Ende der Liste erreicht hat
    $first = $multiSel[0]
    $last = 1
    $step = 1
    EndIf
    $swapString = _GUICtrlListBox_GetSelItemsText($lList)
    _GUICtrlListBox_BeginUpdate($lList)
    For $i = $first To $last Step -$step
    _GUICtrlListBox_DeleteString($lList, $multiSel[$i])
    _GUICtrlListBox_InsertString($lList, $swapString[$i], $multiSel[$i] + $step)
    _GUICtrlListBox_SetSel($lList, $multiSel[$i] + $step)
    Next
    _GUICtrlListBox_EndUpdate($lList)
    EndFunc ;==>_Move

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    P.s.: Bin noch Anfänger und habe mir noch keine einheitliche Notation für die Variablen angewöhnt, daher sind die Variablennamen ziemlich beliebig...
    Falls ein "Profi" das liest: welche Notation sollte man benutzen?

    *edit*
    i2c
    Au weia! Wie peinlich... :cursing:
    Den Befehl hab ich tatsächlich nicht gesehn. Soviel zu meiner Aussage, dass ich noch Anfänger bin :wacko:
    Nuja, vlt kann ich ja mit der Mehrfachauswahl trotzdem noch jemandem helfen...

  • Für ein einfaches, schrittweise verschieben eines einzelnen Eintrags tut es auch

    [autoit]

    _GUICtrlListBox_SwapString()

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

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <WindowsConstants.au3>
    $hGUI = GUICreate("Form1", 317, 141, 192, 148)
    $hListBox = GUICtrlCreateList("", 8, 8, 193, 110, BitOR($LBS_NOTIFY, $LBS_EXTENDEDSEL, $WS_VSCROLL, $WS_BORDER))
    $iButton1 = GUICtrlCreateButton("up", 216, 8, 75, 25)
    $iButton2 = GUICtrlCreateButton("down", 216, 40, 75, 25)
    GUISetState(@SW_SHOW)

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

    _GUICtrlListBox_BeginUpdate($hListBox)
    For $iI = 1 To 9
    $sText = StringFormat("%03d : Random string ", Random(1, 100, 1))
    For $iX = 1 To Random(1, 20, 1)
    $sText &= Chr(Random(65, 90, 1))
    Next
    _GUICtrlListBox_AddString($hListBox, $sText)
    Next
    _GUICtrlListBox_EndUpdate($hListBox)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $iButton1
    $aItems = _GUICtrlListBox_GetSelItems($hListBox)
    If IsArray($aItems) And $aItems[0] > 0 And $aItems[1] > 0 Then
    _GUICtrlListBox_SwapString($hListBox, $aItems[1], $aItems[1] - 1)
    EndIf
    Case $iButton2
    $aItems = _GUICtrlListBox_GetSelItems($hListBox)
    If IsArray($aItems) And $aItems[0] > 0 And $aItems[1] < _GUICtrlListBox_GetCount($hListBox) - 1 Then
    _GUICtrlListBox_SwapString($hListBox, $aItems[1], $aItems[1] + 1)
    EndIf
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Da ich mich mit GUIOnEventMode noch nicht so auskenne habe ich es für mich so angepasst.

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <WindowsConstants.au3>
    #include <File.au3>
    $hGUI = GUICreate("Form1", 317, 141, 192, 148)
    $hListBox = GUICtrlCreateList("", 8, 8, 193, 110, $LBS_STANDARD + $LBS_EXTENDEDSEL + $WS_VSCROLL)
    $iButton1 = GUICtrlCreateButton("up", 216, 8, 75, 25)
    $iButton2 = GUICtrlCreateButton("down", 216, 40, 75, 25)
    $iButton3 = GUICtrlCreateButton("load", 216, 70, 75, 25)
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $iButton3
    $mpath = FileSelectFolder("Choose your Fc2-Map Folder", @UserProfileDir, 1)
    $mfcontent = _FileListToArray($mpath, "*.fc2map")
    For $i = 1 To $mfcontent[0]
    GUICtrlSetData($hListBox, $mfcontent[$i])
    Next
    Case $iButton1
    Up()
    Case $iButton2
    Down()

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

    EndSwitch
    WEnd

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

    Func Down()
    $multiSel = _GUICtrlListBox_GetSelItems($hListBox);==> gibt Array mit den Indizes der ausgewählten Elemente zurück

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

    If $multiSel[$multiSel[0]] = _GUICtrlListBox_GetCount($hListBox) - 1 Then Return ;==> wenn die unterste Auswahl das Ende der Liste erreicht hat
    $first = $multiSel[0]
    $last = 1
    $step = 1

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

    $swapString = _GUICtrlListBox_GetSelItemsText($hListBox)
    For $i = $first To $last Step -$step
    _GUICtrlListBox_DeleteString($hListBox, $multiSel[$i])
    _GUICtrlListBox_InsertString($hListBox, $swapString[$i], $multiSel[$i] + $step)
    _GUICtrlListBox_SetSel($hListBox, $multiSel[$i] + $step)
    Next

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

    EndFunc ;==>Down

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

    Func Up()
    $multiSel = _GUICtrlListBox_GetSelItems($hListBox);==> gibt Array mit den Indizes der ausgewählten Elemente zurück
    If $multiSel[1] < 1 Then Return ;==> wenn die oberste Auswahl den Anfang der Liste erreicht hat
    $first = 1
    $last = $multiSel[0] ;==> $multiSel[0] enthält die Anzahl der ausgewählen Elemente
    $step = -1

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

    $swapString = _GUICtrlListBox_GetSelItemsText($hListBox)
    For $i = $first To $last Step -$step
    _GUICtrlListBox_DeleteString($hListBox, $multiSel[$i])
    _GUICtrlListBox_InsertString($hListBox, $swapString[$i], $multiSel[$i] + $step)
    _GUICtrlListBox_SetSel($hListBox, $multiSel[$i] + $step)
    Next

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

    EndFunc ;==>Up

    [/autoit]

    Wie kann ich es machen das nur Einfach Auswahl möglich ist?
    Leider sind meine Versuche fehlgeschlagen es fehlerfrei hinzukriegen.

    Einmal editiert, zuletzt von VinceA (30. Mai 2013 um 20:00)

  • Da ich mich mit GUIOnEventMode noch nicht so auskenne [...]


    Da gibts eigendlich nicht allzuviel zu verstehen. Meiner Meinung nach sollte man sich aber unbedingt den OnEventMode angewöhnen, allein schon, weil man seine Programme viel übersichtlicher gestalten kann.

    1. Man erstellt eine Gui und weist bestimmten Events Funktionen zu:

    [autoit]

    Opt("GUIOnEventMode", 1)

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

    $wMain = GUICreate("")
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit") ;==> Die Funktion _Exit wird aufgerufen, sobald das "Schließen" Symbol des Fensters geklickt wurde

    [/autoit]


    2. Nun "füllt" man die Gui mit Controls wie z.B. Buttons:

    [autoit]

    $bBtn1 = GUICtrlCreateButton("Button 1", 100, 20)
    GUICtrlSetOnEvent(-1, "_Button1Fkn") ;==> Die Funktion _Button1Fkn wird aufgerufen, wenn "Button 1" gedrückt wird
    $bBtn2 = GUICtrlCreateButton("Button 2", 200, 20)
    GUICtrlSetOnEvent(-1, "_Button2Fkn") ;==> Die Funktion _Button2Fkn wird aufgerufen, wenn "Button 2" gedrückt wird

    [/autoit]


    3. Jetzt noch die Gui anzeigen lassen und in eine Endlosschleife gehn. Das Programm wartet nun, bis einer der Events ausgelöst wird:

    [autoit]

    GUISetState()

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

    While 1
    Sleep(5000)
    WEnd

    [/autoit]


    4. Dahinter (oder an beliebigen Stellen des Skripts) dann die einzelnen Funktionen erstellen:

    [autoit]

    Func _Button1Fkn()
    ;==> hier Event auswerten
    Beep(600, 100)
    EndFunc

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

    Func _Button2Fkn()
    ;==> hier Event auswerten
    Beep(1200, 100)
    EndFunc

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

    Func _Exit()
    Exit
    EndFunc

    [/autoit]


    Wie kann ich es machen das nur Einfach Auswahl möglich ist?
    Leider sind meine Versuche fehlgeschlagen es fehlerfrei hinzukriegen.


    Bitte schön:

    Spoiler anzeigen
    [autoit]

    #include <GuiListBox.au3>
    #include <ListboxConstants.au3>
    #include <WindowsConstants.au3>

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

    Opt("GUIOnEventMode", 1)

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

    $wMain = GUICreate("VerschiebIt mit AutoIt", 300, 300)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

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

    $lList = _GUICtrlListBox_Create($wMain, "", 0, 0, 240, 300);, $LBS_STANDARD + $LBS_EXTENDEDSEL + $WS_VSCROLL)
    $bBtnUp = GUICtrlCreateButton("Hoch", 245, 110, 50)
    GUICtrlSetOnEvent(-1, "_Move")
    $bBtnDown = GUICtrlCreateButton("Runter", 245, 150, 50)
    GUICtrlSetOnEvent(-1, "_Move")

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

    For $i = 1 To 30
    _GUICtrlListBox_AddString($lList, StringFormat("Zeile Nr. %02s und noch'n bisschen Text dazu", $i));==> StringFormat, damit's hübscher aussieht ;)
    Next

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

    GUISetState()

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

    While 1
    Sleep(5000)
    WEnd

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

    Func _Move()
    $curSel = _GUICtrlListBox_GetCurSel($lList)

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

    If @GUI_CtrlId = $bBtnUp Then
    If $curSel < 1 Then Return ;==> wenn die oberste Auswahl den Anfang der Liste erreicht hat
    $step = -1
    Else
    If $curSel = _GUICtrlListBox_GetCount($lList) - 1 Then Return ;==> wenn die unterste Auswahl das Ende der Liste erreicht hat
    $step = 1
    EndIf

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

    _GUICtrlListBox_SwapString($lList, $curSel, $curSel + $step)
    _GUICtrlListBox_SetCurSel($lList, $curSel + $step)
    EndFunc ;==>_Move

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]
  • Vielen dank Friesel für die ausführliche Erklärung über den OnEventMode.
    Das hört sich gut an, werde es auf jeden Fall versuchen anzuwenden.

    Was ich aber noch nicht so ganz kapiere ist die Endlosschleife.

    3. Jetzt noch die Gui anzeigen lassen und in eine Endlosschleife gehn. Das Programm wartet nun, bis einer der Events ausgelöst wird:

    [autoit]

    GUISetState()

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

    While 1
    Sleep(5000)
    WEnd

    [/autoit]

    Mit Sleep (5000), wartet das Programm nun 5 Sekunden bis ein Event ausgelöst wird oder checkt es alle 5 Sekunden ob was passiert.?
    Kann man die 5000 verändern oder ist das eine Vorgabe?

  • Mit Sleep (5000), wartet das Programm nun 5 Sekunden bis ein Event ausgelöst wird oder checkt es alle 5 Sekunden ob was passiert.?
    Kann man die 5000 verändern oder ist das eine Vorgabe?


    Setzt dochmal die Bruchstücke oben zu einem Skript zusammen, dann siehst du, dass es nicht so ist... :D

    Die Endlosschleife mußt du erstellen, da sonst das Programm sofort beendet wird. Die Dauer in Sleep ist beliebig. Wenn du Sleep aber weglässt, steigt die CPU-Last, weil das Programm ja dann unentwegt zwischen While und Wend "rotiert".
    Sobald einer der überwachten Events auftritt, reagiert das Programm darauf, daher OnEventMode :rock:


    *edit*
    Ups! Das Wichtigste für den GuiOnEventMode habe ich vergessen. Am Anfang muß dieser natürlich noch aktiviert werden mit:

    [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit]


    Ist oben in den "Bruchstücken" jetzt korrigiert...

    *edit²*
    "Überaschenderweise" findet man auch so einiges in der Hilfe :rofl:
    GUI-Referenz - GUI-Konzepte -> ganz unten: GUI-Ereignis-Modi
    GUI-Referenz - MessageLoop Modus
    GUI-Referenz - OnEvent Modus

  • Ok, ich vertsehe es jetzt. :)

    Ich habe noch sehr viel zu lernen. :S

    Für ein Anfänger ohne jegliche Vorkenntnisse ist die Hilfe nicht immer sehr einfach zu verstehen da braucht es doch Jemand der einem das Schritt für Schritt erhlärt um die ganze Logik zu verstehen.

    Vielen Dank Friesel für deine Mühe, danke auch an i2c. :)