如何在ListView中实现拖动行?并且如何保存拖动后行的位置?
我想实现对ListView中的内容能够任意的拖动改变位置,查了很长时间不知道怎么搞,哪位高人请指点一下?谢谢![ 本帖最后由 sd007 于 2009-3-21 19:30 编辑 ] 请高人指点一下,谢谢 #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 编辑 ] 很好用,非常感谢你的代码! 高手。向你学习! 改进建议:修改为更通用性的,譬如Func _DragItems($thelv),以及适用于任何个子ITEM的LISTVIEW。。
再次楼主的做法思路,太棒了,呵呵,终于不用手动按纽一次次的调整LV顺序了 这是我的代码应用,须注意:
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 刚好想用类代码,参考参考,谢谢分享 实用的代码。谢谢分享。
页:
[1]