Seite 1 von 2

Treeview nachträglich richtig füllen

Verfasst: 31.05.2011 18:33
von Frabbing
Mein Programm soll, während es läuft, ein Treeview nach und nach auffüllen.
Im Reiter "Einer" sollen alle Einträge mit 1 landen, in Zweier alle mit 2, usw. Bekomme das aber nicht hin, es wird immer wahllos irgendwohin einsortiert.

http://frabbing.bplaced.net/pic.png

Das Beispiel unten macht so natürlich nicht viel Sinn. Demonstriert aber sicher, was ich beabsichtige..
Wie müsste ich den Code ändern, dass richtig (alle Einsen unter "Einer", Zweien unter "Zweier" usw.) sortiert wird?

Code: Alles auswählen

OpenWindow(0, 0, 0, 600, 400, "Test")
TreeGadget(1, 0, 0, 600, 400) 
AddGadgetItem(1, -1, "Einer")
AddGadgetItem(1, -1, "Zweier", 0, 0)
AddGadgetItem(1, -1, "Dreier", 0, 0)

; Die Füllung des Treeview soll nachträglich
; erfolgen, also im Laufe des Programms.
; Wird hier als Schleife simuliert
;
For k = 1 To 20
  i = Random(2) + 1
  AddGadgetItem(1, i, Str(i), 0, 1)            
Next

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

Re: Treeview nachträglich richtig füllen

Verfasst: 31.05.2011 19:09
von Kiffi
Hallo Frank,

durch das Hinzufügen von ChildNodes änderst Du die Position
der Parentnodes 2 und 3 (Parent 1 bleibt immer an Position 1).
Deswegen kannst Du die 2 nicht immer an Position 2 einfügen,
denn wenn Parent 1 bereits ein Child hat, ist Parent 2 nicht mehr
an Position 2.

So könnte man es lösen:

Code: Alles auswählen

OpenWindow(0, 0, 0, 600, 400, "Test")
TreeGadget(1, 0, 0, 600, 400) 

AddGadgetItem(1, -1, "Einer")
SetGadgetItemData(1,CountGadgetItems(1)-1, 1)

AddGadgetItem(1, -1, "Zweier")
SetGadgetItemData(1,CountGadgetItems(1)-1, 2)

AddGadgetItem(1, -1, "Dreier")
SetGadgetItemData(1,CountGadgetItems(1)-1, 3)

; Die Füllung des Treeview soll nachträglich
; erfolgen, also im Laufe des Programms.
; Wird hier als Schleife simuliert
;

Procedure GetTreeNodeByGadgetItemData(ItemData)
  
  For Counter = 0 To CountGadgetItems(1) - 1
    If GetGadgetItemData(1, Counter)=ItemData
      ProcedureReturn Counter + 1
    EndIf
  Next
  
  
EndProcedure

For k = 1 To 20
  i = Random(2) + 1
  AddGadgetItem(1, GetTreeNodeByGadgetItemData(i), Str(i), 0, 1)            
Next

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Grüße ... Kiffi

Re: Treeview nachträglich richtig füllen

Verfasst: 31.05.2011 19:14
von ts-soft
Hier die einfache Variante zum verständnis:

Code: Alles auswählen

OpenWindow(0, 0, 0, 600, 400, "Test")
TreeGadget(1, 0, 0, 600, 400)
AddGadgetItem(1, -1, "Einer")
AddGadgetItem(1, -1, "Zweier", 0, 0)
AddGadgetItem(1, -1, "Dreier", 0, 0)


;
AddGadgetItem(1, 1, "1", 0, 1)
AddGadgetItem(1, 3, "2", 0, 1)
AddGadgetItem(1, 5, "3", 0, 1)

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

Re: Treeview nachträglich richtig füllen

Verfasst: 31.05.2011 19:28
von Frabbing
Hey, danke euch! Habe ich - denke ich - soweit verstanden. :D
Die Lösung per ItemData kann ich so leider nicht benutzen, weil dort noch zusätzliche Daten gespeichert werden sollen. Ich schau mal, wie ich das noch anders lösen kann.

:allright:

Re: Treeview nachträglich richtig füllen

Verfasst: 31.05.2011 19:35
von ts-soft
Frabbing hat geschrieben:Die Lösung per ItemData kann ich so leider nicht benutzen, weil dort noch zusätzliche Daten gespeichert werden sollen.
1. In den ItemData kannst Du auch den Pointer zu einer Strukturierten Variable speichern, es passen also unendlich viele Daten hinein.
2. Nach dem Titel des Items suchen, wenn dieser eindeutig ist, sollte meist auch gehen.

Re: Treeview nachträglich richtig füllen

Verfasst: 15.06.2011 16:48
von Frabbing
Bin leider auf ein unerwartetes Problem gestossen. Wenn ich nach Kiffis Methode Texte nachträglich einsortiere, kehrt sich die Reihenfolge um. Um das zu verdeutlichen, habe ich noch Buchstaben absteigend zu den Zahlen dazu gegeben, beginnend mit A. Die Buchstaben werden aber immer nach unten weiter geschoben, d.h. der neue Eintrag landet darunter, statt darüber.
Schwer zu erklären, testet mal Kiffis leicht erweiterten Code:

Code: Alles auswählen

OpenWindow(0, 0, 0, 600, 400, "Test")
TreeGadget(1, 0, 0, 600, 400)

AddGadgetItem(1, -1, "Einer")
SetGadgetItemData(1,CountGadgetItems(1)-1, 1)

AddGadgetItem(1, -1, "Zweier")
SetGadgetItemData(1,CountGadgetItems(1)-1, 2)

AddGadgetItem(1, -1, "Dreier")
SetGadgetItemData(1,CountGadgetItems(1)-1, 3)

; Die Füllung des Treeview soll nachträglich
; erfolgen, also im Laufe des Programms.
; Wird hier als Schleife simuliert
;

Procedure GetTreeNodeByGadgetItemData(ItemData)
 
  For Counter = 0 To CountGadgetItems(1) - 1
    If GetGadgetItemData(1, Counter)=ItemData
      ProcedureReturn Counter + 1
    EndIf
  Next
 
 
EndProcedure

For k = 1 To 20
  i = Random(2) + 1
  AddGadgetItem(1, GetTreeNodeByGadgetItemData(i), Chr(65+k) + Str(i), 0, 1)           
Next

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow


Was muss ich ändern, damit die Buchstaben absteigend einsortiert werden? (bitte nicht verwechseln mit sortierten Treeviews, ich möchte nicht sortieren, sondern nur passend einfügen). :coderselixir:

Re: Treeview nachträglich richtig füllen

Verfasst: 15.06.2011 17:08
von Kiffi
Hallo Frank,

meine Proc ermittelt immer den ParentNode mit dem entsprechenden ItemData
und fügt hinter diesen das neue ChildNode ein. Deswegen erscheinen die Childs
in umgekehrter Reihenfolge (von oben nach unten).

Die Proc muss so erweitert werden, dass jeweils das letzte Child des ItemData-Parents
ermittelt wird (GetGadgetItemAttribute() in Zusammenhang mit #PB_Tree_SubLevel).
Hinter diesen kannst Du dann Dein neues Child einfügen.

Grüße ... Kiffi

Re: Treeview nachträglich richtig füllen

Verfasst: 15.06.2011 17:53
von Frabbing
Soweit klar. Ich muss also die höchste bislang vergebene Nummer checken und dann überprüfen, ob dessen Parent auch das richtige ist. Wenn nicht, dann die nächst-niederigere Nummer nehmen. Sehe ich das richtig? Aber wie ermittle ich den Parent eines Childs?

Re: Treeview nachträglich richtig füllen

Verfasst: 15.06.2011 18:24
von ts-soft
Lösung hatte ich zwar schon angedeutet, aber ... :wink:

Code: Alles auswählen

EnableExplicit

Procedure InsertItem(Node.s, value.i)
  Protected Count, i, Found
  
  Count = CountGadgetItems(1)
  For i = 0 To Count - 1
    If GetGadgetItemAttribute(1, i, #PB_Tree_SubLevel) = 0
      If GetGadgetItemText(1, i) = Node
        Found = #True
        Break
      EndIf
    EndIf
  Next
  If Found
    i + 1
    While GetGadgetItemAttribute(1, i, #PB_Tree_SubLevel) = 1
      i + 1
    Wend
    AddGadgetItem(1, i, Str(value), 0, 1)
  EndIf
EndProcedure

OpenWindow(0, 0, 0, 600, 400, "Test")
TreeGadget(1, 0, 0, 600, 400)

AddGadgetItem(1, -1, "Einer")
SetGadgetItemData(1,CountGadgetItems(1)-1, 1)

AddGadgetItem(1, -1, "Zweier")
SetGadgetItemData(1,CountGadgetItems(1)-1, 2)

AddGadgetItem(1, -1, "Dreier")
SetGadgetItemData(1,CountGadgetItems(1)-1, 3)

InsertItem("Zweier", 1)
InsertItem("Zweier", 2)
InsertItem("Einer", 1)
InsertItem("Dreier", 3)
InsertItem("Zweier", 3)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow : Break
  EndSelect
ForEver
Gruß
Thomas

Re: Treeview nachträglich richtig füllen

Verfasst: 15.06.2011 22:51
von Frabbing
Super, danke! :allright:
Jetzt scheint es stabil zu laufen. Hab aber doch nicht die Lösung mit Strings genommen, sondern per Daten. Denke, das ist schneller.

Hier die erweiterte Proc, wenn das später noch jemand gebrauchen muss:

Code: Alles auswählen

Procedure GetTreeNodeByGadgetItemData(ItemData)
  
  
  For Counter = 0 To CountGadgetItems(#procview) - 1
    If GetGadgetItemData(#procview, Counter) = ItemData
      If GetGadgetItemAttribute(#procview, counter, #PB_Tree_SubLevel) = 0
        Break
      EndIf
    EndIf
  Next
  
  counter + 1
  
  While GetGadgetItemAttribute(#procview, counter, #PB_Tree_SubLevel) = 1
    counter + 1
  Wend
    
  ProcedureReturn counter
    
EndProcedure