找回密码
 加入
搜索
查看: 6888|回复: 13

[GUI管理] ListView列数据自动排列(已解决)

  [复制链接]
发表于 2011-9-26 02:48:32 | 显示全部楼层 |阅读模式
本帖最后由 nmgwddj 于 2011-9-26 21:38 编辑

之前一直在为这个问题头大,搜索了一下帮助文档,看到_GUICtrlListView_SimpleSort函数有这个功能。

虽然_GUICtrlListView_SimpleSort能设置非第一列的数据自动排列,但是总在感觉上过不去,每添加一条数据到ListView控件中,就要使用_GUICtrlListView_SimpleSort排列一次。

看了看listview的样式中,$LVS_SORTASCENDING样式可以让listview自动排列,但是只对第一列生效,我如果有多列,又不想让数据按第一列的排序,只能用_GUICtrlListView_SimpleSort了。

就是想了解一下,是否可以像$LVS_SORTASCENDING样式一样,直接设置按某列自动排序,添加数据的时候不用再调用_GUICtrlListView_SimpleSort排列了。这样感觉上过得去一些。
发表于 2011-9-26 03:51:58 | 显示全部楼层
说个不太好的但是相对容易点的办法,先设置要排序的那列为首列,排序之后,再对列进行设置,[1,2,3,4]==>[2,1,3,4],大概意思吧
发表于 2011-9-26 08:37:45 | 显示全部楼层
之前一直在为这个问题头大,搜索了一下帮助文档,看到_GUICtrlListView_SimpleSort函数有这个功能。

虽然 ...
nmgwddj 发表于 2011-9-26 02:48


你这是属于典型的眼见了心要烦,象$LVS_SORTASCENDING那样给你个黑箱,你就不焦虑了,其实其内部实现,还是一样原理:每插入一次,就得调用一下排序。
还是来个任何语言都会教授的二分法排序来玩一下吧


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

Local $hListView, $aRet, $index

GUICreate("ListView", 600, 400)
$hListView = GUICtrlCreateListView("Auto_Sorted", 20, 20, 550, 350)
GUISetState(@SW_SHOW)

$aRet = _Random_Array()

_GUICtrlListView_BeginUpdate($hListView)

For $i = 1 To $aRet[0]
    $index = _GetSortedIndex($hListView, $aRet[$i])
    _GUICtrlListView_InsertItem($hListView, $aRet[$i], $index)
Next

_GUICtrlListView_SetColumnWidth($hListView, 0, $LVSCW_AUTOSIZE)
_GUICtrlListView_EndUpdate($hListView)

Do
Until Sleep(10) * GUIGetMsg() == -3


Func _GetSortedIndex($hListView, $item)
    Local $iCount = _GUICtrlListView_GetItemCount($hListView)
    Local $iStart = 0, $iEnd = $iCount, $iMid = Int($iEnd/2)
        
        If $iCount == 0 Then Return        
    While ($iEnd - $iStart) > 10
        If StringCompare($item, _GUICtrlListView_GetItemText($hListView, $iMid)) <= 0 Then
            $iEnd = $iMid
            $iMid -= Int(($iEnd - $iStart) / 2)
        Else
            $iStart = $iMid
            $iMid += Int(($iEnd - $iStart) / 2)
        EndIf
    WEnd
    For $i = $iStart To $iEnd
        If StringCompare($item, _GUICtrlListView_GetItemText($hListView, $i)) <= 0 Then Return $i
    Next
EndFunc


Func _Random_Array()
    Local $array[201] = [200], $string = ''
    For $i = 1 To 200
        $string = ''
        For $j = 1 To 10
            $string &= Chr(Random(97, 122))
        Next
        $array[$i] = $string
    Next
    Return $array
EndFunc
 楼主| 发表于 2011-9-26 11:43:44 | 显示全部楼层
回复 2# netegg


    这个方法可行,不过不知道listview能不能将第二列设置为首列,让其根据第二列来排列数据,相关函数翻了翻,没有中意的,自己也不知道怎么写。。。
 楼主| 发表于 2011-9-26 11:44:18 | 显示全部楼层
回复 3# happytc


    可行的方法,看来总之还是要排列了。
 楼主| 发表于 2011-9-26 11:47:21 | 显示全部楼层
没办法,我写的插入数据的时候不排列数据,从新读取的时候或者重新打开程序的时候再排列。
中间加上了点击列自动排列的功能,感觉这样已经够完美了。一会上段代码。
 楼主| 发表于 2011-9-26 11:52:25 | 显示全部楼层
本帖最后由 nmgwddj 于 2011-9-26 11:54 编辑

无聊,就是练手,所以有这么多问题,公司点餐比较麻烦,还要一个人一个人的问,就做了一个这么个工具,客户端还没做呢。先把服务端界面整合出来。

涉及一些sqllite的操作,还是看以前老前辈做的东西琢磨的。点餐时间和通讯方面还没着手做呢。

其中就第一列用了排列功能。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-9-26 12:07:46 | 显示全部楼层
为何不在数组中排序?
 楼主| 发表于 2011-9-26 12:13:54 | 显示全部楼层
回复 8# 3mile


    请教,因为个人基础比较差,思路能否借鉴下。
发表于 2011-9-26 12:39:28 | 显示全部楼层
本帖最后由 netegg 于 2011-9-26 19:08 编辑

[au3]#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


$Gui = GUICreate("Test", 300, 200)
$hListView = GUICtrlCreateListView("Client | Status", 5, 0, 290, 250)
GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)

For $a = 1 To 8
    If $a = 4 Then
        GUICtrlCreateListViewItem("PC" & $a & "| Offline", $hListView)
    Else
        GUICtrlCreateListViewItem("PC" & $a & "| Online", $hListView)
    EndIf
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListView)]

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    Sleep(10)
WEnd
Exit

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"))
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $LVN_COLUMNCLICK
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    _GUICtrlListView_SimpleSort($hWndListView, $B_DESCENDING, DllStructGetData($tInfo, "SubItem"))
            EndSwitch
    EndSwitch
Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY[/au3]

讨论的这么麻烦,这样算是个没有偷梁换柱的办法吧.不过又想了想,好像和lz的要求有点区别,可能需要用_sendmessage自动一下
发表于 2011-9-26 20:29:13 | 显示全部楼层
讨论的这么麻烦,这样算是个没有偷梁换柱的办法吧.不过又想了想,好像和lz的要求有点区别,可能需要用_sen ...
netegg 发表于 2011-9-26 12:39



    明显跟楼主要求有区别了
总结一句话,楼主要求就是:要在代码里看不到调用排序的语句就行。
发表于 2011-9-26 21:29:13 | 显示全部楼层
那只有先排序再填入了
 楼主| 发表于 2011-9-26 21:38:39 | 显示全部楼层
回复 10# netegg


    学习学习,已经不必纠结,其实并不影响使用,能到达效果即可。

主要还是我这个东西有些别扭,第一列设计的时候就不是按数字排序的,这怪我设计错误。
发表于 2011-10-16 13:11:24 | 显示全部楼层
不错的学习资料,多谢前辈分享
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-6 09:29 , Processed in 0.082294 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表