# ReOrdering Wx::TreeCtrl Items

**URL:** <https://www.ruby-forum.com/t/reordering-wx-treectrl-items/124567>\
**Category:** wxRuby\
**Created:** [December 30, 2007, 10:25am UTC](https://www.ruby-forum.com/t/reordering-wx-treectrl-items/124567 "2007-12-30T10:25:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![EchoB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/45deac/32.png) [@EchoB](https://www.ruby-forum.com/u/EchoB)\
**Post date:** [December 30, 2007, 10:25am UTC](https://www.ruby-forum.com/t/reordering-wx-treectrl-items/124567/1 "2007-12-30T10:25:10Z")

</div>

Given the following hash:  
#…  
@project\_list = {  
‘Contract0’ =\> nil,  
‘Contract1’ =\> {  
‘Project1’ =\> nil,  
‘Project2’ =\> nil,  
‘Project3’ =\> {  
‘task1’ =\> nil,  
‘task2’ =\> nil,  
‘task3’ =\> nil  
}  
},  
‘Contract3’ =\> {  
‘Project1’ =\> nil  
},  
‘Contract4’ =\> nil,  
‘Contract5’ =\> nil,  
‘Contract6long contract with Characters ~!!@#$!@$%#$&$^&(^&()’ =\>  
nil,  
‘Contract7’ =\> nil,  
‘Contract8’ =\> nil,  
‘Contract9’ =\> nil  
}  
#…  
#And Given the following code:  
#…  
@tc\_project\_list = Wx::TreeCtrl.new(self, :size =\>  
Wx::Size.new(175, 150), :style =\> Wx::TR\_HIDE\_ROOT | Wx::TR\_EDIT\_LABELS  
| Wx::TR\_HAS\_BUTTONS | Wx::TR\_LINES\_AT\_ROOT)  
tcr\_project\_root = @tc\_project\_list.add\_root(“Project List”)  
populate\_project\_tree(@project\_list, tcr\_project\_root)  
#…  
#…  
def populate\_project\_tree(h\_project\_list, parent\_node)  
h\_project\_list.each {|key, value|  
tree\_node = @tc\_project\_list.append\_item(parent\_node,  
key.to\_s)  
if value.class.to\_s == “Hash”  
populate\_project\_tree(value, tree\_node)  
end  
}  
end  
#…  
#==================================  
The big picture is to be able to populate the tree control and then  
re-order (NOT sorting) the items in the tree control. Is this possible?  
I have looked in the examples and haven’t found anything like this. I  
suspect it is possible with the get sibling functions, but I haven’t  
been able to piece together a way to accomplish this yet.  
Anyone have any ideas?

Also I am noticing an odd thing (and I’m sure this must be something I’m  
doing) - When looking at my TreeCtrl - Contract0/Contract1 show up at  
the _bottom_ of the list, not at the top. Contract3 is at the top.

---

<div class="post-metadata">

**Author:** ![EchoB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/45deac/32.png) [@EchoB](https://www.ruby-forum.com/u/EchoB)\
**Post date:** [January 3, 2008, 12:20am UTC](https://www.ruby-forum.com/t/reordering-wx-treectrl-items/124567/2 "2008-01-03T00:20:59Z")

</div>

Hi

EchoB wrote:

> The big picture is to be able to populate the tree control and then  
> re-order (NOT sorting) the items in the tree control. Is this possible?

There’s two ways to sort a TreeCtrl. Either

1. Subclass TreeCtrl and create an on\_compare\_items method in your  
subclass. This will be called whenever the ‘sort\_items’ is called. The  
method will be passed pairs of TreeItem ids to compare, and should  
return -1, 0 or 1 to indicate whether the first item comes before, equal  
to or after the second item.

[http://wxruby.rubyforge.org/doc/treectrl.html#TreeCtrl\_oncompareitems](http://wxruby.rubyforge.org/doc/treectrl.html#TreeCtrl_oncompareitems)

1. Maintain the order of the items as they are inserted.  
TreeCtrl#append\_item is commonly used in the samples and adds the new  
item as the last child of the specified parent. But you can also add  
items to the tree using TreeCtrl#insert\_item and #insert\_item\_before.  
With these you pass an additional argument to specify where the new item  
should be placed relative to the existing children of the parent item:

[http://wxruby.rubyforge.org/doc/treectrl.html#TreeCtrl\_insertitem](http://wxruby.rubyforge.org/doc/treectrl.html#TreeCtrl_insertitem)

The second way is probably better (simpler, more efficient) if the  
project/task children in your example should always be shown in the same  
order. 1) is really useful if you want the user to be able to vary the  
order in which children are shown, for example, if you want them to be  
able to order by start date OR end date OR name.

As a side hint in case you hadn’t seen this feature, if the items in a  
TreeCtrl are closely linked to program or database objects like a  
“Project” or “Task”, look into using item\_data (which can be passed as  
an argument to insert/append) to maintain that link. It means the  
TreeCtrl can work like a Ruby hash using get\_item\_data. This will make  
sorting the items easier.

Note that there is no method in Wx to _move_ a TreeItem. It must be  
deleted and re-inserted/re-appended somewhere else.

> Also I am noticing an odd thing (and I’m sure this must be something I’m  
> doing) - When looking at my TreeCtrl - Contract0/Contract1 show up at  
> the _bottom_ of the list, not at the top. Contract3 is at the top.  
> This is because in ruby 1.8 the order in which key/value pairs are added  
> to a hash isn’t guaranteed to be the order in which calling “each” and  
> similar will yield the pairs. Hashes, unlike Arrays, aren’t ordered.  
> Testing your example with ruby 1.8, Contract3 _is_ the first key yielded  
> by each.

This changes in Ruby 1.9, in which hash is ordered and “each” will  
return the items in your example in order they’re declared.

cheers  
alex
