Jump to content

Sort a subtree in treeview


rexx
 Share

Recommended Posts

Hi,

I want to know how to sort a subtree in treeview.

I use _GUICtrlTreeView_Sort($hWnd) but it only sort the root tree.

Also found this but it sorts all, what i what is sort only a specified (the selected) subtree.

I tried to use the subtree item handle as $hWnd but nothing changed.

Thanks in advance.

Link to comment
Share on other sites

Try this:

#include <GUIConstantsEx.au3>
#Include <GuiTreeView.au3>
#include <Array.au3>
Local $gui, $tv, $bt, $r_desc, $hSel, $desc, $aItem[4]

$gui = GUICreate('test')
$tv = GUICtrlCreateTreeView(10, 10, 200, 300)
$aItem[0] = GUICtrlCreateTreeViewItem('Item_1', $tv)
$aItem[1] = GUICtrlCreateTreeViewItem('Item_2', $tv)
$aItem[2] = GUICtrlCreateTreeViewItem('Item_3', $tv)
$aItem[3] = GUICtrlCreateTreeViewItem('Item_4', $tv)
For $i = 0 To 3
    For $n = 1 To 10
        GUICtrlCreateTreeViewItem(_GetRandomStr(8), $aItem[$i])
    Next
Next
$bt = GUICtrlCreateButton('sort selected Item', 220, 10, 150, 20)
GUICtrlCreateGroup('', 220, 40, 170, 40)
GUICtrlCreateRadio('ascending', 230, 55, 70)
GUICtrlSetState(-1, $GUI_CHECKED)
$r_desc = GUICtrlCreateRadio('descending', 305, 55, 80)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            Exit
        Case $bt
            $hSel = _GUICtrlTreeView_GetSelection($tv)
            $desc = 0
            If BitAND(GUICtrlRead($r_desc), $GUI_CHECKED) Then $desc = 1
            If $hSel Then _sortOneParent($tv, $hSel, $desc)
    EndSwitch
WEnd

Func _sortOneParent($hWnd, $hSel, $desc=0) ; sorts ascending, with $desc=1 sorts descending
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, $hSel)
    If Not $hChild Then Return
    Local $arhwndChild[1] = [$hChild], $artextChild[1] = [_GUICtrlTreeView_GetText($hWnd, $hChild)]
    While 1
        $hChild = _GUICtrlTreeView_GetNextSibling($hWnd, $hChild)
        If Not $hChild Then ExitLoop
        ReDim $arhwndChild[UBound($arhwndChild)+1]
        ReDim $artextChild[UBound($artextChild)+1]
        $arhwndChild[UBound($arhwndChild)-1] = $hChild
        $artextChild[UBound($artextChild)-1] = _GUICtrlTreeView_GetText($hWnd, $hChild)
    WEnd
    _ArraySort($artextChild, $desc)
    _GUICtrlTreeView_BeginUpdate($hWnd)
    For $i = 0 To UBound($arhwndChild) -1
        _GUICtrlTreeView_SetText($hWnd, $arhwndChild[$i], $artextChild[$i])
    Next
    _GUICtrlTreeView_EndUpdate($hWnd)
EndFunc

Func _GetRandomStr($len)
    Local $aChar = StringSplit('01234AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz56789','')
    Local $str = ''
    For $i = 1 To $len
        $str &= $aChar[Random(1,$aChar[0],1)]
    Next
    Return $str
EndFunc

Best Regards BugFix  

Link to comment
Share on other sites

Thanks!

But if there're multi level submenu it goes wrong.

it only changed the text, but it didn't move an item's children.

for example

#include <GUIConstantsEx.au3>
#Include <GuiTreeView.au3>
#include <Array.au3>
Local $gui, $tv, $bt, $r_desc, $hSel, $desc, $aItem[4]

$gui = GUICreate('test')
$tv = GUICtrlCreateTreeView(10, 10, 200, 300)
$aItem[0] = GUICtrlCreateTreeViewItem('Item_1', $tv)
$aItem[1] = GUICtrlCreateTreeViewItem('Item_2', $tv)
$aItem[2] = GUICtrlCreateTreeViewItem('Item_3', $aItem[1])
$aItem[3] = GUICtrlCreateTreeViewItem('Item_4', $aItem[2])
For $i = 0 To 3
    For $n = 1 To 10
        GUICtrlCreateTreeViewItem(_GetRandomStr(8), $aItem[$i])
    Next
Next
$bt = GUICtrlCreateButton('sort selected Item', 220, 10, 150, 20)
GUICtrlCreateGroup('', 220, 40, 170, 40)
GUICtrlCreateRadio('ascending', 230, 55, 70)
GUICtrlSetState(-1, $GUI_CHECKED)
$r_desc = GUICtrlCreateRadio('descending', 305, 55, 80)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            Exit
        Case $bt
            $hSel = _GUICtrlTreeView_GetSelection($tv)
            $desc = 0
            If BitAND(GUICtrlRead($r_desc), $GUI_CHECKED) Then $desc = 1
            If $hSel Then _sortOneParent($tv, $hSel, $desc)
    EndSwitch
WEnd

Func _sortOneParent($hWnd, $hSel, $desc=0) ; sorts ascending, with $desc=1 sorts descending
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, $hSel)
    If Not $hChild Then Return
    Local $arhwndChild[1] = [$hChild], $artextChild[1] = [_GUICtrlTreeView_GetText($hWnd, $hChild)]
    While 1
        $hChild = _GUICtrlTreeView_GetNextSibling($hWnd, $hChild)
        If Not $hChild Then ExitLoop
        ReDim $arhwndChild[UBound($arhwndChild)+1]
        ReDim $artextChild[UBound($artextChild)+1]
        $arhwndChild[UBound($arhwndChild)-1] = $hChild
        $artextChild[UBound($artextChild)-1] = _GUICtrlTreeView_GetText($hWnd, $hChild)
    WEnd
    _ArraySort($artextChild, $desc)
    _GUICtrlTreeView_BeginUpdate($hWnd)
    For $i = 0 To UBound($arhwndChild) -1
        _GUICtrlTreeView_SetText($hWnd, $arhwndChild[$i], $artextChild[$i])
    Next
    _GUICtrlTreeView_EndUpdate($hWnd)
EndFunc

Func _GetRandomStr($len)
    Local $aChar = StringSplit('01234AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz56789','')
    Local $str = ''
    For $i = 1 To $len
        $str &= $aChar[Random(1,$aChar[0],1)]
    Next
    Return $str
EndFunc
Edited by rexx
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...