sd007 发表于 2009-3-16 18:35:01

如何在ListView中实现拖动行?并且如何保存拖动后行的位置?

我想实现对ListView中的内容能够任意的拖动改变位置,查了很长时间不知道怎么搞,哪位高人请指点一下?谢谢!

[ 本帖最后由 sd007 于 2009-3-21 19:30 编辑 ]

sd007 发表于 2009-3-20 19:56:26

请高人指点一下,谢谢

pusofalse 发表于 2009-3-20 20:45:46

#include <GuiListView.au3>
#include <WindowsConstants.au3>

$hGui = GuiCreate("Test", 400, 300)

$lvExStyle = bitOr($lvs_ex_fullrowselect, $lvs_ex_gridlines, _
                $lvs_ex_doublebuffer, $ws_ex_clientedge)

Global $iFlag = False
$lv = GuiCtrlCreateListView("Test|Drag", 5, 5, 390, 280, $lvs_report, $lvExStyle)
For $o = 1 to 10
        $Item = "Item " & $o & "|Sub Item " & $o & " - 1"
        GuiCtrlCreateListViewItem($Item, $lv)
Next

GuiSetState()
GuiRegisterMsg($wm_notify, "_wmNotify")

Do
Until        GuiGetMsg() = -3

Func _WmNotify($hWnd, $iMsg, $wParam, $lParam)
        Local $tNmhdr, $iCode
        $tNmhdr = DllStructCreate($tagNmhdr, $lParam)
        $iCode = DllStructGetData($tNmhdr, "code")
        If $wParam = $lv Then
                Switch $iCode
                Case $lvn_beginDrag
                        $iFlag = True       
                Case $lvn_hotTrack
                        If not $iFlag Then Return False
                        $iFlag = False
                        _DragItems()
                EndSwitch
        EndIf
        $tNmhdr = 0
EndFunc        ;==>_WmNotify()

Func _DragItems()
        Local $selection = _GuiCtrlListView_GetSelectedIndices($lv, true)
        If $selection = 0 then Return False
        Local $selectionText
        For $d = 0 to $selection - 1
                For $x = 0 to 1
                        $selectionText[$d][$x] = _GuiCtrlListView_GetItemText($lv, $selection[$d+1], $x)
                Next
        Next
        _GuiCtrlListView_DeleteItemsSelected(GuiCtrlGetHandle($lv))
        Local $cursor = GuiGetCursorInfo($hGui)
        Local $lvsPos = ControlGetPos($hGui, "", $lv)
        $lvsPos = $cursor - $lvsPos
        $lvsPos = $cursor - $lvsPos
        $InsertPos = _GuiCtrlListView_HitTest($lv, $lvsPos, $lvsPos)
        If $InsertPos = -1 then $InsertPos = _GuiCtrlListView_GetItemCount($lv)
        For $d = $selection - 1 to 0 step - 1
                _GuiCtrlListView_InsertItem($lv, $selectionText[$d], $InsertPos, 0)
                _GuiCtrlListView_AddSubItem($lv, $InsertPos, $selectionText[$d], 1,1)
        Next
EndFunc        ;==>_DragItems()


[ 本帖最后由 pusofalse 于 2009-3-20 20:51 编辑 ]

sd007 发表于 2009-3-21 19:29:53

很好用,非常感谢你的代码!

luke 发表于 2009-3-21 20:40:28

高手。向你学习!

llztt 发表于 2009-3-21 22:15:37

改进建议:修改为更通用性的,譬如Func _DragItems($thelv),以及适用于任何个子ITEM的LISTVIEW。。

再次楼主的做法思路,太棒了,呵呵,终于不用手动按纽一次次的调整LV顺序了

sd007 发表于 2009-3-23 16:52:04

这是我的代码应用,须注意:
1.ListView的第一列是数据库表的字段ID值
2.数据库表中有一个orderid字段,用于排序(从大到小排列)

ListView_DragItems($Form1,$ListView1,数据库表名)

;改进后的_DragItems(),支持多列
Func ListView_DragItems($hForm,$hWnd,$tableName="")
      Local $selection = _GuiCtrlListView_GetSelectedIndices($hWnd, true)
      If $selection = 0 then Return False
      $tmpItemLs=_GUICtrlListView_GetItemTextArray($hWnd, $selection);得到列数$tmpItemLs
      Local $selectionText[$selection][$tmpItemLs+1]
      For $d = 0 to $selection - 1
            $tmp=_GUICtrlListView_GetItemTextArray($hWnd, $selection[$d+1])
                For $x = 0 to $tmpItemLs
                        $selectionText[$d][$x] = _GuiCtrlListView_GetItemText($hWnd, $selection[$d+1], $x)
                Next
      Next
      _GuiCtrlListView_DeleteItemsSelected($hWnd)
      Local $cursor = GuiGetCursorInfo($hForm)
      Local $lvsPos = ControlGetPos($hForm, "", $hWnd)
      $lvsPos = $cursor - $lvsPos
      $lvsPos = $cursor - $lvsPos
      $InsertPos = _GuiCtrlListView_HitTest($hWnd, $lvsPos, $lvsPos)
      If $InsertPos = -1 then $InsertPos = _GuiCtrlListView_GetItemCount($hWnd)
      SaveSortToSql(_GuiCtrlListView_GetItemText($hWnd, $InsertPos-1),$selectionText,$tableName);将排序保存到数据库
   For $d = $selection - 1 to 0 step - 1
                _GuiCtrlListView_InsertItem($hWnd, $selectionText[$d], $InsertPos, 0)
                For $x = 1 to $tmpItemLs
                  _GuiCtrlListView_AddSubItem($hWnd, $InsertPos, $selectionText[$d][$x], $x,1)
                Next
      Next
EndFunc

;将排序保存到数据库
Func SaveSortToSql($ItemRsId,$selectionText,$tableName="")
      If $tableName="" Then return
    If $ItemRsId="" Then;当拖动到最上面时
            $orderid=GetRs_2("select orderid from "&$tableName&" order by orderid desc",1);从数据库中查询最大的orderid
                $orderid=$orderid+1
      Else
            $orderid=GetRs_2("select orderid from "&$tableName&" where id="&$ItemRsId&"",1);得到要插入在哪个Item后面的orderid
                $orderid=$orderid
            ExecSQL("update "&$tableName&" set orderid=orderid+"&ubound($selectionText)&" where orderid>="&$orderid&"");将大于orderid的所有记录的orderid都增加ubound($selectionText)
      EndIf
      For $i = 0 to ubound($selectionText)-1
                ExecSQL("update "&$tableName&" set orderid="&$orderid + (ubound($selectionText)-1-$i)&" where id="&$selectionText[$i]&"")
      Next
EndFunc

曼菲士 发表于 2011-12-11 16:26:20

刚好想用类代码,参考参考,谢谢分享

damoo 发表于 2014-3-28 09:39:16

实用的代码。谢谢分享。
页: [1]
查看完整版本: 如何在ListView中实现拖动行?并且如何保存拖动后行的位置?