on 08-22-2014 7:25 PM
I have a parent-child data in a datawindow from a table mytab(id, pid....)
Then I want to use to data to create a tree in treeview.
I try to use recursive function, but have problem with datawindow as I use filter to change the data in datawindow.
here is my code:
of_addnode(treeviewitem node, rootrow):
int li_rows,li_newitem, i
treeviewitem li_tvitem
dw_1.SetFilter("pid = " + string(node.data))
dw_1.Filter( )
li_rows = dw_1.RowCount()
if li_rows = 0 then
return
end if
for i = 1 to li_rows
li_tvitem.level = node.level +1
li_tvitem.data = dw_1.GetItemNumber(i,"id")
li_tvitem.label = dw_1.GetItemString(i,"description")
li_tvitem.pictureindex = 1
li_tvitem.selectedpictureindex = 2
li_newitem = tv_1.insertitemsort (rootrow, li_tvitem) // insert a new node
of_addnode(li_tvitem,li_newitem)
dw_1.SetFilter("pid = " + string(node.data)) //restore data back to filter, problem here. tree will have duplicate item
dw_1.Filter( )
next
how to create a recursive function from one datasource datawindow for this case?
Try using a datastore, see below. I haven't tested that but I think that should work.
of_addnode(treeviewitem node, rootrow):
int li_rows,li_newitem, i
treeviewitem li_tvitem
datastore lds_1
dw_1.SetFilter("pid = " + string(node.data))
dw_1.Filter( )
lds_1 = Create DataStore
lds_1.DataObject = dw_1.DataObject
lds_1.ImportString(dw_1.describe("datawindow.data"))
li_rows = lds_1.RowCount()
if li_rows = 0 then
return
end if
for i = 1 to li_rows
li_tvitem.level = node.level +1
li_tvitem.data = lds_1.GetItemNumber(i,"id")
li_tvitem.label = lds_1.GetItemString(i,"description")
li_tvitem.pictureindex = 1
li_tvitem.selectedpictureindex = 2
li_newitem = tv_1.insertitemsort (rootrow, li_tvitem) // insert a new node
of_addnode(li_tvitem,li_newitem)
I'm not sure if you would need this filter here... maybe to clear out the filter you need to specify empty string...
as dw_1.SetFilter('')
dw_1.SetFilter("pid = " + string(node.data)) //restore data back to filter, problem here. tree will have duplicate item
dw_1.Filter( )
next
destroy lds_1
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You really should have a different datastore for each level, retrieve it in the itempopulate event and add the treeview items there. It will be much faster because only the nodes you are actually looking at are retrieved & created.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
You have 2 problems here :
1- You are using a single table with columns "id" and "parent_id". For example in the table
employee in EASdemodb, you have emp_id and manager_id.
The problem is how you set the manager_id for the Top Managers. In the table employee,
there are 2 Top managers and the emp_id is the same than the manager_id for these employees.
So in you filter, you have to add for sub-level nodes a CLAUSE :
AND employee_manager_id <> employee_emp_id
2-the second problem is when you change the filter for sub_levels and then get back
to the parent and set the parent filter, you are not guaranteed that the Rows order is the same
as before.
So when you call GetItemNumber, you may have a different row value.
This is why you get duplication labels in your treeview.
The solution is to set a Sort order to the datawindow :
ids_employees.SetFilter(ls_current_filter)
ids_employees.Filter( )
ids_employees.setsort("employee_emp_id")
ids_employees.Sort()
See below my function of_populate (treeviewitem atvi_item, long ll_parent)
For the first call , set ll_parent = 0
Hope this Helps.
Abdallah.
//-------------------------------------------------------------------------
int li_rows, li_newitem, li, li_level
treeviewitem ltvi_tem
string ls_parent_filter, ls_current_filter
if isValid (atvi_item) AND ll_parent > 0 Then
ls_parent_filter = ids_employees.Describe("DataWindow.Table.Filter")
ls_current_filter = "employee_manager_id = " + string(atvi_item.data) + " AND employee_manager_id <> employee_emp_id"
ltvi_tem.level = atvi_item.level + 1
ELSE
ls_parent_filter = "employee_manager_id = employee_emp_id"
ls_current_filter = "employee_manager_id = employee_emp_id"
li_level = 0
END IF
ids_employees.SetFilter(ls_current_filter)
ids_employees.Filter( )
ids_employees.setsort("employee_emp_id")
ids_employees.Sort()
li_rows = ids_employees.RowCount()
for li = 1 TO li_rows
ltvi_tem.level = li_level
ltvi_tem.data = ids_employees.GetItemNumber (li, "employee_emp_id")
ltvi_tem.label = ids_employees.GetItemString (li, "employee_emp_fname") + " " + ids_employees.GetItemString (li, "employee_emp_lname")
ltvi_tem.pictureindex = 1
ltvi_tem.selectedpictureindex = 2
li_newitem = tv_1.insertitemsort (ll_parent, ltvi_tem) // insert a new node
of_populate (ltvi_tem, li_newitem)
next
ids_employees.SetFilter(ls_parent_filter)
ids_employees.Filter( )
return 1
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
If you must use code like this, filtering the datawindow or datastore whilst trying to read from it as you are is just going to create pain.
Why not use the query from your existing datawindow as the datasource for a treeview datawindow? If your front end can't access the database then get the data from a datastore and load it into the treeview datawindow (as you're already trying to do).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
93 | |
11 | |
10 | |
9 | |
9 | |
7 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.