Toon posts:

[VB.NET/C#] Recursive Functie / Nodes Achterhalen ?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleempje met een treeview (jaja, alweer :)).

Het probleem is als volgt:

code:
1
2
3
4
5
6
(rootnode) Bestandsoverzicht
                         \   Producten
                                   \  Multivers lijn
                                             \  Multivers Lite
                                             \  Multivers Extended
                         \   Diensten


Nu is het mogelijk dat de gebruiker een node kan aanklikken, dan dan een actie daarop uitvoeren (verwijderen van een node, of aanmaken van een nieuwe node). Echter omdat alle items in de database staan komen er bij mij ook database functies in voor. Ook maak ik gebruik van sorteringen, en daar is met name waar dit probleem over gaat.
Nu is het sorteren (en het maken van een sorteer string) geen probleem maar wel het volgende:

Ik probeer bij welke subnode je ook zit de node onder de rootnode te achterhalen
Normaal gesproken kan dit met Node.Parent.Text. Wat ik dus ook doe, is dat ik die items (Producten, Diensten etc) heb ik in een collection staan. Dus daar is de boel mee te vergelijken.

Ik dacht van ik maak een recusieve functie om iig alle items eens in een collection/arraylist te zetten zodat ik kan zien hoe het werkt. .... Maar, waar kwam ik achter is dat hij maar 1 laagje diep gaat, en dat is dus niet de bedoeling.

Ik heb het geprobeerd met de volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    Sub GetValuesTest(ByVal N As TreeNode, ByRef V As ArrayList)
        'V.Add(N.Text)
        '  V.Add(N.Parent.Text)

        Dim i, intNodeCount As Integer
        intNodeCount = N.Nodes.Count

        For i = 0 To intNodeCount Step 1
            V.Add(N.Parent.Text)
            For Each tn As TreeNode In N.Nodes
                GetValuesTest(tn, V)
            Next
        Next i
    End Sub

Sub ikwordaangesproken()
 Dim Arraylisttest As New ArrayList
 GetValuesTest(tvCBbestandsoverzicht.SelectedNode, Arraylisttest)
End sub

PS: let ff niet op de belachelijke namen, gaat dus puur ff om te testen.

Maar ik kom er dus niet uit, kan een van jullie me op weg helpen ?

[ Voor 2% gewijzigd door Verwijderd op 01-11-2004 10:28 . Reden: Layout Fix0r ]


  • Remco
  • Registratie: Januari 2001
  • Laatst online: 19-05 17:38

The best thing about UDP jokes is that I don't care if you get them or not.


Verwijderd

Topicstarter
Ja ik heb daar al gekeken, het is notabene me eigen topic :)
In ieder geval, waar het dus in dit geval meer om gaat is dat hij dus niet verder terug wilt maar dat x.SelectedNode dus niet voldoende inlaad om de onderliggende nodes te achterhalen ?

Of zit ik met die functie, totaal fout ? (die in de openingspost)

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Euhm.. ik begrijp er niks van 8)7 .

Wat doet ie For i=0 to... -lus?
Die klopt allereerst al niet, want je gaat die lus nu dus (intNodeCount +1) keer door. Dat kan niet de bedoeling zijn.

En waarom zet je in die lus dan (intNodeCount +1)x N.Parent.Text in de array?

En moet
code:
1
For Each tn As TreeNode In N.Nodes

dan niet
code:
1
For Each tn As TreeNode In N.Parent.Nodes
ofzoiets zijn (ik weet het niet, ik zeg maar wat).
Of alleen N.Parent (maar dan heb je geen array nodig).

Als je omhoog wilt, dan heb je geen For-Next nodig, want er is natuurlijk maar één parent.

Maargoed, ik begrijp het nog niet zo goed; of ligt dat aan mij :?

30Drie Web Design & IT Consultancy | Raven Consultancy Services


Verwijderd

Topicstarter
Chief.NET schreef op 01 november 2004 @ 10:46:
Euhm.. ik begrijp er niks van 8)7 .

Wat doet ie For i=0 to... -lus?
Die klopt allereerst al niet, want je gaat die lus nu dus (intNodeCount +1) keer door. Dat kan niet de bedoeling zijn.

En waarom zet je in die lus dan (intNodeCount +1)x N.Parent.Text in de array?

En moet
code:
1
For Each tn As TreeNode In N.Nodes

dan niet
code:
1
For Each tn As TreeNode In N.Parent.Nodes
ofzoiets zijn (ik weet het niet, ik zeg maar wat).
Of alleen N.Parent (maar dan heb je geen array nodig).

Als je omhoog wilt, dan heb je geen For-Next nodig, want er is natuurlijk maar één parent.

Maargoed, ik begrijp het nog niet zo goed; of ligt dat aan mij :?
Misschien ben ik niet even duidelijk geweest.
Ik wil dus door *een* manier zien te achterhalen(waar ik ook zit in de treeview) wat het submenu item is (onder de rootnode).

Dus het volgende: Multivers Extended,
edit: er van uit gaande dat multivers extended de node is welke is geselecteerd
die vergelijkt hij met een collection (en de items die daar in zitten, zoals producten en diensten) dan moet hij nog een laag verder diep gaan, dan komt ie uit bij "Multivers-lijn" die staat ook niet in dat lijstje van de collection, dan komt hij bij "Producten", die staat wel in de collection. En daar gaat hij dan een andere functie/procedure op loslaten (in dit geval een string combineren, voor te sorteren).

Ik heb in principe die for-next lus ook niet nodig, het was puur voor te testen dat werkte duidelijk niet :P

[ Voor 4% gewijzigd door Verwijderd op 01-11-2004 10:55 ]


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Maar dan ben je hiermee al klaar:
code:
1
2
3
4
5
6
    Sub GetValuesTest(ByVal N As TreeNode, ByRef V As ArrayList)
        V.Add(N.Text)
        If Not N.Parent is Nothing then
                GetValuesTest(N.Parent, V)
        End If
    End Sub

Dan heb je een lijst die begint bij de diepste Node, en gaat dan steeds verder omhoog.
Je hoeft dan alleen die lijst af te lopen tot je wat vindt.

Snap ik he nu wel :?

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Err, waarom gebruik je geen node.FullPath ? Je krijgt dan het volledige pad vanaf de rootnode totaan je huidige node. Door de separator goed te kiezen kun je meteen de node vinden die je wilt mbv split. 2 regels code.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Topicstarter
Chief.NET schreef op 01 november 2004 @ 11:01:
Maar dan ben je hiermee al klaar:
code:
1
2
3
4
5
6
    Sub GetValuesTest(ByVal N As TreeNode, ByRef V As ArrayList)
        V.Add(N.Text)
        If Not N.Parent is Nothing then
                GetValuesTest(N.Parent, V)
        End If
    End Sub

Dan heb je een lijst die begint bij de diepste Node, en gaat dan steeds verder omhoog.
Je hoeft dan alleen die lijst af te lopen tot je wat vindt.

Snap ik he nu wel :?
Ahhh, dus zo werkt het. Bij mij bleef dat ding maar 1 laag diep hangen.
Bij jou stukje code blijft hij doorlopen, wat dus precies de bedoeling was.
Nu kan ik er dus me code bijschrijven dat wanneer hij Producten tegenkomt (die in de collection staat) dat hij een andere functie aanspreekt.

Bedankt voor het voorbeeld...
EfBe schreef op 01 november 2004 @ 11:17:
Err, waarom gebruik je geen node.FullPath ? Je krijgt dan het volledige pad vanaf de rootnode totaan je huidige node. Door de separator goed te kiezen kun je meteen de node vinden die je wilt mbv split. 2 regels code.
Dit had ik idd ook al ondervonden, echter ik heb ook nog geen ervaring met het uitkleden van een string (wel samenvoegen van), vandaar dat ik dus het bovenstaande idee toepas. Dat wordt voor een privé projectje dat ik dat ontleden van strings ga bekijken...

Allen bedankt !

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Verwijderd schreef op 01 november 2004 @ 11:24:
[...]
Dit had ik idd ook al ondervonden, echter ik heb ook nog geen ervaring met het uitkleden van een string (wel samenvoegen van), vandaar dat ik dus het bovenstaande idee toepas. Dat wordt voor een privé projectje dat ik dat ontleden van strings ga bekijken...

Allen bedankt !
Daar is [String].Split voor uitgevonden :) .
En als splitkarakter kan je TreeView.PathSeparator gebruiken.

Is eigenlijk veel simpeler.. |:(

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

Wat eigenlijk nog veel eenvoudiger is, is om je object-instanties op te slaan in de tags van de treenodes.
Zorg er voor dat elke class die je in je treenodes opslaat een interface voor een eigen context-menu heeft, en al dat gepriel is niet nodig (als ik de vraag goed begrepen heb).

Verwijderd

Topicstarter
Chief.NET schreef op 01 november 2004 @ 12:06:
[...]


Daar is [String].Split voor uitgevonden :) .
En als splitkarakter kan je TreeView.PathSeparator gebruiken.

Is eigenlijk veel simpeler.. |:(
Een collega (welke ook programmeur is) legde dit net ook uit aan mij ;)
Maar toch bedankt... 't is een stuk makkelijker dan ik had verwacht.
D4Skunk schreef op 01 november 2004 @ 12:13:
Wat eigenlijk nog veel eenvoudiger is, is om je object-instanties op te slaan in de tags van de treenodes.
Zorg er voor dat elke class die je in je treenodes opslaat een interface voor een eigen context-menu heeft, en al dat gepriel is niet nodig (als ik de vraag goed begrepen heb).
Dit is dan weer blabla voor mij ;) (lees: stapje te hoog)

  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

Met het oog op het onderhoud van je source-code ben je beter je informatie niet van je treeview af te leiden.
Wanneer je dit toch doet en later besluit je user-interface te herwerken, moet je je volledige programma herschrijven.
Een voorbeeldje hoe het dan wel moet:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Fubar {
   private string name;
   private Fubar  rootFubar;

   public string Name {
    get { return name; }
    set { name=value; }
   }

   public Fubar RootFubar {
    get { return rootFubar; }
    set { rootFubar=value; }
   }
}


veronderstel dat je de treenode 'tn' wilt gebruiken
en dus ipv
code:
1
2
string root;
root = FindRootNode (TreeNode tn );


gebruik je dit :
code:
1
2
3
string root;
Fubar tmp=(Fubar)tn.Tag;
root=tmp.RootFubar.Name;


Bij het invullen van je treenodes gebruik je de volgende code :
code:
1
2
3
4
Foreach(Fubar f in fubars) {
   TreeNode tn=treeNodes.Add(f.Name);
   tn.Tag=f;
}


Je slaat dus als het ware je object instance op bij elke node in je treeview.

Hopelijk is dit iets duidelijker... 8)

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

D4Skunk schreef op 02 november 2004 @ 13:52:
Met het oog op het onderhoud van je source-code ben je beter je informatie niet van je treeview af te leiden.
Wanneer je dit toch doet en later besluit je user-interface te herwerken, moet je je volledige programma herschrijven.
Een voorbeeldje hoe het dan wel moet:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Fubar {
   private string name;
   private Fubar  rootFubar;

   public string Name {
    get { return name; }
    set { name=value; }
   }

   public Fubar RootFubar {
    get { return rootFubar; }
    set { rootFubar=value; }
   }
}


veronderstel dat je de treenode 'tn' wilt gebruiken
en dus ipv
code:
1
2
string root;
root = FindRootNode (TreeNode tn );


gebruik je dit :
code:
1
2
3
string root;
Fubar tmp=(Fubar)tn.Tag;
root=tmp.RootFubar.Name;


Bij het invullen van je treenodes gebruik je de volgende code :
code:
1
2
3
4
Foreach(Fubar f in fubars) {
   TreeNode tn=treeNodes.Add(f.Name);
   tn.Tag=f;
}


Je slaat dus als het ware je object instance op bij elke node in je treeview.

Hopelijk is dit iets duidelijker... 8)
Het hangt ook wel af waar de informatie vandaan komt.
Als alle nodes uit een database komen, kan ik me voorstellen dat je gewoon die text weergeeft (als je in de database de FullPath opslaat, zodat dat uniek is)
Of anders alleen de PK in de Tag-property zet.

30Drie Web Design & IT Consultancy | Raven Consultancy Services

Pagina: 1