Treeview nachträglich richtig füllen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Frabbing
Beiträge: 160
Registriert: 15.02.2007 21:31
Kontaktdaten:

Treeview nachträglich richtig füllen

Beitrag 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
Gruß, Frank
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Treeview nachträglich richtig füllen

Beitrag 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
a²+b²=mc²
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Treeview nachträglich richtig füllen

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Frabbing
Beiträge: 160
Registriert: 15.02.2007 21:31
Kontaktdaten:

Re: Treeview nachträglich richtig füllen

Beitrag 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:
Gruß, Frank
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Treeview nachträglich richtig füllen

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Frabbing
Beiträge: 160
Registriert: 15.02.2007 21:31
Kontaktdaten:

Re: Treeview nachträglich richtig füllen

Beitrag 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:
Gruß, Frank
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Treeview nachträglich richtig füllen

Beitrag 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
a²+b²=mc²
Benutzeravatar
Frabbing
Beiträge: 160
Registriert: 15.02.2007 21:31
Kontaktdaten:

Re: Treeview nachträglich richtig füllen

Beitrag 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?
Gruß, Frank
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Treeview nachträglich richtig füllen

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Frabbing
Beiträge: 160
Registriert: 15.02.2007 21:31
Kontaktdaten:

Re: Treeview nachträglich richtig füllen

Beitrag 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
Gruß, Frank
Antworten