Inhalt eines ListViewItems editieren??

  • Ist es möglich, den Inhalt eines ListViewItems zu editieren?
    Bsp:

    Code
    $l1 = GUICtrlCreateListView("1|2|3|4", 0, 20, 500, 250, $LVS_EDITLABELS)
    GUICtrlCreateListViewItem("Test1|Test2|Test3|Test4, $l1)


    Wie man hier sieht, probiere ich es über $LVS_EDITLABELS. Allerdings ist dann immer nur der erste Teil des Items editierbar, hier also "Test1".
    Wie bekomme ich es hin, dass ich z.B. "Test3" bearbeiten kann?

    Einmal editiert, zuletzt von penta.phoenix (13. Juni 2008 um 08:34)

  • Moin,

    aus der Hilfe:

    GUICtrlCreateListViewItem

    Zitat

    Remarks

    This function creates the individual ListView items that can be selected. The items function as normal controls and can be set with GUICtrlSetData.
    Items can be deleted as with any other control by using GUICtrlDelete.
    ListView items can be dragged and drop into an Edit or Input control with a $GUI_DROPACCEPTED state.
    See GUICtrlCreateListView about resizing of the column.


    GUICtrlSetData

    Zitat

    Remarks

    For Combo or List control :
    If the "data" corresponds to an already existing entry it is set as the default.
    If the "data" starts with GUIDataSeparatorChar or is an empty string "" the previous list is destroyed.

    For ListView, ListViewItem controls :
    To update a specific column just forget about the others ie "||update" to update 3rd column.
    If "update" is empty the column/subitem will be erased. For example "|" will erase the second column/subitem, "" will erase the first.


    Gruß
    Greenhorn


  • Sorry, da hab ich mich wohl blöd ausgedrückt.
    Ich möchte nur den Inhalt per Hand verändern(umschreiben, kopieren).
    Folgendes Szenario: Es werden Daten ausgelesen und diese werden in einem ListViewItem angezeigt.
    Nun möchte ich ich diese manuell verändern und evtl. kopieren und nicht mit einem vorgegebenen Befehl den Inhalt ersetzen, da dieser variabel ist.
    Mit $LVS_EDITLABELS ist das wie gesagt zumindest für den ersten Teil der Daten möglich.
    Aber wenn ich ein Item mit dem Inhalt "Das|ist|der|Inhalt" habe, dann kann ich damit nur den Teil "Das" bearbeiten, nicht aber den Rest.

  • Zitat

    To update a specific column just forget about the others ie "||update" to update 3rd column.

    [autoit]

    $l1 = GUICtrlCreateListView("1|2|3|4", 0, 20, 500, 250)
    GUICtrlSetData($l1, 'Das|ist|der|Inhalt')

    [/autoit]

    Das funktioniert nicht ?
    Was meinst Du mit manuell ? Markieren und bearbeiten wie beim Umbenennen im Explorer ?
    Das sollte eigentlich mit $LVS_EDITLABELS möglich sein, so wie Du es schon hast ...

    Ich habe noch nicht mit ListView gearbeitet, von daher auch keine praktische Erfahrung damit ...


    Gruß


  • Doch, was Du schreibst funktioniert.
    Aber ich meine, Inhalt anklicken, umschreiben.
    Also wie das Umbenennen im Explorer.
    Es ist auch mit $LVS_EDITLABELS möglich, aber komischerweise immer nur für den ersten Teil des Item.
    In meinem letzten Beispiel könnte ich den "Das"-Teil verändern, nicht aber z.B. den "der"-Teil.

  • Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    Opt("GUIOnEventMode", 1)
    GUICreate("test", 300, 110)
    $listview = GUICtrlCreateListView("a|b|c|", 5, 5, 290, 100)
    $listviewitem = GUICtrlCreateListViewItem("1|2|3", $listview)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")
    GUICtrlSetOnEvent($listviewitem, "_test")
    GUISetState()

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

    While 1
    WEnd

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

    Func _test()
    $input = InputBox("Neuer Wert", "Bitte Wert für '3' eingeben")
    GUICtrlSetData($listviewitem, "1|2|"&$input)
    EndFunc

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

    Func _exit()
    Exit
    EndFunc

    [/autoit]

    Du kannst das aber auch so machen:

    [autoit]

    GUICtrlSetData(@GUI_CtrlId, "1|2|"&$input) ;im oberen Script Zeile 16

    [/autoit]

    sowas in der art?

    MFG FireFlyer

    *Paradox ist, wenn man sich im Handumdrehen den Fuss bricht* :D

    2 Mal editiert, zuletzt von FireFlyer (12. Juni 2008 um 14:36)

  • Ja, über einen Umweg wäre es möglich.
    Auf jeden Fall mal: Danke.

    Aber eigentlich dachte ich wirklich an Markieren, Doppelklick, Ändern/Kopieren.
    In dem speziellen Fall sind es Pfade, die evtl. angepasst werden müssen(deshalb ändern) oder wo anders eingetragen werden müssen(deshalb kopieren).
    Wenn ich jetzt jedes mal erst ein ListViewItem markieren muss, dann den Itemteil mit dem Pfad auslese und dann kopiere, ist das eindeutig umständlicher, als wenn ich das von Hand mache.

    Wenn aber niemand etwas anderes einfällt, mache ich es so, wie FireFlyer es vorschlägt.

    • Offizieller Beitrag

    Hi,
    also SubItems lassen sich leider so nicht bearbeiten. Ich hab dir aber mal eine recht passable Lösung gebastelt.
    Beachte, dass der Style $LVS_EDITLABELS hierbei nicht aktiviert sein darf.
    Per Doppelklick auf einen Eintrag wird ein kleines Editfenster an dieser Position geöffnet. Das Ereignis zum Schließen des Fensters ist ENTER nach Ändern des Inhalts. Darum habe ich zusätzlich ESC als HotKey zum Schließen aktiviert, falls keine Änderung vorgenommen wird (sonst könnte das Fenster nicht geschlossen werden :) ).

    Spoiler anzeigen
    [autoit]

    #include<StaticConstants.au3>
    #include<GUIConstantsEx.au3>
    #include<ListViewConstants.au3>
    #include<StructureConstants.au3>
    #include<WindowsConstants.au3>
    #include <GUIListView.au3>
    Opt("GUIOnEventMode", 1)
    Global $currentItem[2], $title

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

    $gui = GUICreate('test')
    GUISetOnEvent($GUI_EVENT_CLOSE, '_ende')
    $hListView = GUICtrlCreateListView('Spalte1|Spalte2|Spalte3', 10, 10, 300, 200, $LVS_REPORT)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 70)
    _GUICtrlListView_SetColumnWidth($hListView, 1, 60)
    _GUICtrlListView_SetColumnWidth($hListView, 2, $LVSCW_AUTOSIZE_USEHEADER )
    For $i = 1 To 9
    GUICtrlCreateListViewItem('Z. ' & $i & ' - Sp. 1|Z. ' & $i & ' - Sp. 2|Z. ' & $i & ' - Sp. 3', $hListView)
    Next

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

    $EditBox = GUICreate('', 200, 30, -1, -1, BitOR($WS_POPUP,$WS_BORDER), $WS_EX_TOPMOST)
    $edit = GUICtrlCreateInput('', 5, 5, 190, 20, $SS_CENTER)
    GUICtrlSetOnEvent(-1, '_EditEnter')
    HotKeySet('{ESC}', '_escEdit')

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

    GUISetState(@SW_SHOW, $gui)
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

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

    While True
    Sleep(100)
    WEnd

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

    Func _LeftDblClick($Info)
    If $Info[3] = -1 Then Return
    _GUICtrlListView_SetSelectedColumn($Info[1], $Info[4])
    $title = WinGetTitle($gui)
    Local $mouse = MouseGetPos(), $wndEdit = WinGetPos($EditBox)
    Local $wndGUI = WinGetPos($gui), $wndLV = ControlGetPos($gui, '', $hListView)
    Local $colInfo = _GUICtrlListView_GetColumn($Info[1], $Info[4]), $sumWidth = 0, $tmp
    WinSetTitle($gui, '', 'Editiere: Zeile ' & $Info[3]+1 & ', ' & $colInfo[5])
    For $i = 0 To $Info[4]
    $tmp = _GUICtrlListView_GetColumn($Info[1], $i)
    $sumWidth += $tmp[4]
    Next
    $sumWidth -= $colInfo[4]
    Local $xPos = $wndGUI[0]+$wndLV[0]+$sumWidth
    If $xPos+$colInfo[4]+10 > @DesktopWidth Then $xPos = @DesktopWidth - ($colInfo[4] + 10)
    WinMove($EditBox, '', $xPos, $mouse[1]-$wndEdit[3], $colInfo[4]+10)
    GUICtrlSetData($edit, _GUICtrlListView_GetItemText($Info[1], $Info[3], $Info[4]))
    $currentItem[0] = $Info[3]
    $currentItem[1] = $Info[4]
    GUISetState(@SW_SHOW, $EditBox)
    EndFunc

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

    Func _escEdit()
    WinSetTitle($gui, '', $title)
    GUISetState(@SW_HIDE, $EditBox)
    EndFunc

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

    Func _EditEnter()
    WinSetTitle($gui, '', $title)
    _GUICtrlListView_SetItemText($hListView, $currentItem[0], GUICtrlRead($edit), $currentItem[1])
    GUISetState(@SW_HIDE, $EditBox)
    EndFunc

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

    Func _ende()
    Exit
    EndFunc

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

    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
    Case $hWndListView
    Switch $iCode
    Case $NM_DBLCLK ; Sent by a list-view control when the user double-clicks an item with the left mouse button
    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    Local $aInfo[12] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "lParam"), _
    DllStructGetData($tInfo, "KeyFlags")]
    _LeftDblClick($aInfo)
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

    [/autoit]


    Edit: Hab nach eine Codezeile eingefügt, um zu verhindern, dass bei einem Klick am rechten Bildschirmrand, das Eingabefenster außerhalb des Desktopbereiches erscheint.
    Edit2: Noch eine Verbesserung, das Eingabefenster paßt sich automatisch an die Breite der angeklickten Spalte an.
    Und wegen der besseren Optik markieren wir auch gleich noch die Spalte ;)

    Und noch ein bischen geschraubt :D
    Das Eingabefenster liegt jetzt immer exakt über der angeklickten Spalte.

    Noch eine Erweiterung: während des Editierens werden im Fenstertitel Zeilennummer und Spaltenbezeichnung angezeigt.

  • Hey, das ist ja genial.
    Für den Moment habe ich es anders gelöst.
    Sollte meine Methode aber nicht auf Zustimmung(immer die Vorgesetzten :D ) stoßen, werde ich es mit deiner machen.