Results 1 to 27 of 27

Thread: sort only a specific node in a treeview

Hybrid View

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2007
    Posts
    44

    sort only a specific node in a treeview

    I've A treeview with parent nodes and all parents have also childrens. i need to sort only the childrens in one of the parent nodes without sorting the parent nodes in the treeview because i want to keep the order of the parents.

    how can i do this

    thanks

  2. #2
    PowerPoster VBDT's Avatar
    Join Date
    Sep 2005
    Location
    CA - USA
    Posts
    2,922

    Re: sort only a specific node in a treeview

    How do you want to sort the nodes? By what property?

    The tree node class doesn’t have sort capability but you can create a class that inherit from TreeNode class and add the sort functionality. Here I put some code for you that will sort the nodes under the parent node by their text property.

    Here is the new node class

    Code:
    Public Class MyNode
        Inherits TreeNode : Implements IComparable(Of MyNode)
    
        Sub New()
            MyBase.New()
        End Sub
    
        Sub New(ByVal text As String)
            MyBase.New(text)
        End Sub
    
        Public Sub Sort()
            Me.Sort(0, Me.Nodes.Count, Nothing)
        End Sub
    
        Public Sub Sort(ByVal index As Integer, ByVal count As Integer, ByVal comparer As IComparer(Of MyNode))
            Dim nodes(Me.Nodes.Count - 1) As MyNode
            Me.Nodes.CopyTo(nodes, 0)
            Array.Sort(Of MyNode)(nodes, index, count, comparer)
            Me.Nodes.Clear()
            Me.Nodes.AddRange(nodes)
        End Sub
    
        Public Function CompareTo(ByVal other As MyNode) As Integer Implements System.IComparable(Of MyNode).CompareTo
            Return Me.Text.CompareTo(other.Text)
        End Function
    End Class
    And this is how you implement it
    Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Sort test
        Dim pn As New MyNode("Parent")
        pn.Nodes.Add(New MyNode("a"))
        pn.Nodes.Add(New MyNode("c"))
        pn.Nodes.Add(New MyNode("b"))
        pn.Nodes.Add(New MyNode("d"))
        pn.Nodes.Add(New MyNode("a"))
        pn.Sort()
        TreeView1.Nodes.Add(pn)
    End Sub
    Attached Images Attached Images  

  3. #3

    Thread Starter
    Member
    Join Date
    Dec 2007
    Posts
    44

    Re: sort only a specific node in a treeview

    thank you for your advice
    but lets say I want to add a child node called "a1" under "a" and "b1" under "b".
    how do I do this

  4. #4
    PowerPoster VBDT's Avatar
    Join Date
    Sep 2005
    Location
    CA - USA
    Posts
    2,922

    Re: sort only a specific node in a treeview

    Hi, I guess your question is how to add nodes to the “MyNode” object. The “MyNode” class is the same TreeNode class since it inherits from it, so that it has all the functionality of the TreeNode class and an additional “Sort” functionality.

    You simple add chilled nodes to the parent node as you do with TreeNode object, no difference.

  5. #5

    Thread Starter
    Member
    Join Date
    Dec 2007
    Posts
    44

    Re: sort only a specific node in a treeview

    Hi, sorry that I can't figure out how to add child node to "a" node and than to "b" node and so on.
    can you give me an example please

    thank you

  6. #6
    PowerPoster VBDT's Avatar
    Join Date
    Sep 2005
    Location
    CA - USA
    Posts
    2,922

    Re: sort only a specific node in a treeview

    'Here is one way
    Code:
    Dim pn As New MyNode("Parent")
    'create a-node
    Dim aN As New MyNode("a")
    'add a1-node to a-node
    aN.Nodes.Add(New MyNode("a1"))
    'add a-node to the parent node
    pn.Nodes.Add(aN)
    sort all parent's chilled nods
    pn.Sort()
    'add parent node to tree view control
    TreeView1.Nodes.Add(pn)
    'Here is the second way
    Code:
    'create parent node
    Dim pn As New MyNode("Parent")
    Dim index As Integer
    'add a-node to parent
    index = pn.Nodes.Add(New MyNode("a"))
    'add a1-node to a-node
    pn.Nodes(index).Nodes.Add("a1")
    'sort all parent's chilled nods
    pn.Sort()
    'add parent node to tree view control
    TreeView1.Nodes.Add(pn)

  7. #7

    Thread Starter
    Member
    Join Date
    Dec 2007
    Posts
    44

    Re: sort only a specific node in a treeview

    hi
    with your first example:
    '===================
    Dim pn As New MyNode("Parent")
    'create a-node
    Dim aN As New MyNode("a")
    'add a1-node to a-node
    aN.Nodes.Add(New MyNode("a1"))
    'add a-node to the parent node
    pn.Nodes.Add(aN)
    sort all parent's chilled nods
    pn.Sort()
    'add parent node to tree view control
    TreeView1.Nodes.Add(pn)
    '======================
    how can I attach an Icon to pn node and another icon to aN nodes and so on


    thanks

  8. #8
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    This appears to be a slick way to sort a treenode before you add it to an treeview.

    Any way to sort a treenode after it's part of a treeview?

  9. #9
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    23,223

    Re: sort only a specific node in a treeview

    try this:
    Attached Files Attached Files

  10. #10
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    PERFECT (almost)!!! Including NOT sorting the children of the sorted node!

    however...

    When I place the extensions module code in my own module, I get an error on "...instance.Cast..." saying ['Cast' is not a member of 'System.Windows.Forms.TreeNodeCollection'].

    Ugh, so close. I've been fighting this one for days... Any ideas?

  11. #11
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    23,223

    Re: sort only a specific node in a treeview

    which version of vb.net are you using?
    it won't work pre vb2008

  12. #12
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    2010

    I'm trying to find which .NET version my project is referencing because it was converted from VB 2005, so it's probably 2.0? Can this be changed? In the Advanced Compiler Settings the Target Framework says .NET Framework 3.5.

  13. #13
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    23,223

    Re: sort only a specific node in a treeview

    cast is a part of LINQ.
    here's the references you'll need:
    Attached Images Attached Images  

  14. #14
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    23,223

    Re: sort only a specific node in a treeview

    it's probably an upgrade issue, so check your references

  15. #15
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    System.Core is missing but when I try to add it, it says that it can't add it because it's added automatically.
    Attached Images Attached Images  

  16. #16
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    23,223

    Re: sort only a specific node in a treeview

    ok i found it. in your projects .vbproj file:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.21022</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{00D9E78D-099A-40BC-97C0-D18A4D140C2F}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <StartupObject>WindowsApplication1.My.MyApplication</StartupObject>
    <RootNamespace>WindowsApplication1</RootNamespace>
    <AssemblyName>sort treenode collection</AssemblyName>
    <FileAlignment>512</FileAlignment>
    <MyType>WindowsForms</MyType>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <OptionExplicit>On</OptionExplicit>
    <OptionCompare>Binary</OptionCompare>
    <OptionStrict>On</OptionStrict>
    <OptionInfer>On</OptionInfer>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <DefineDebug>true</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <OutputPath>bin\Debug\</OutputPath>
    <DocumentationFile>sort treenode collection.xml</DocumentationFile>
    <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <DefineDebug>false</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DocumentationFile>sort treenode collection.xml</DocumentationFile>
    <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
    </PropertyGroup>
    <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Core">
    <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Xml.Linq">
    <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    </ItemGroup>
    <ItemGroup>
    <Import Include="Microsoft.VisualBasic" />
    <Import Include="System" />
    <Import Include="System.Collections" />
    <Import Include="System.Collections.Generic" />
    <Import Include="System.Drawing" />
    <Import Include="System.Diagnostics" />
    <Import Include="System.Windows.Forms" />
    <Import Include="System.Linq" />
    <Import Include="System.Xml.Linq" />
    </ItemGroup>
    <ItemGroup>
    <Compile Include="extensions.vb" />
    <Compile Include="Form1.vb">
    <SubType>Form</SubType>
    </Compile>
    <Compile Include="Form1.Designer.vb">
    <DependentUpon>Form1.vb</DependentUpon>
    <SubType>Form</SubType>
    </Compile>
    <Compile Include="My Project\AssemblyInfo.vb" />
    <Compile Include="My Project\Application.Designer.vb">
    <AutoGen>True</AutoGen>
    <DependentUpon>Application.myapp</DependentUpon>
    </Compile>
    <Compile Include="My Project\Resources.Designer.vb">
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="My Project\Settings.Designer.vb">
    <AutoGen>True</AutoGen>
    <DependentUpon>Settings.settings</DependentUpon>
    <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    </ItemGroup>
    <ItemGroup>
    <EmbeddedResource Include="Form1.resx">
    <DependentUpon>Form1.vb</DependentUpon>
    <SubType>Designer</SubType>
    </EmbeddedResource>
    <EmbeddedResource Include="My Project\Resources.resx">
    <Generator>VbMyResourcesResXFileCodeGenerator</Generator>
    <LastGenOutput>Resources.Designer.vb</LastGenOutput>
    <CustomToolNamespace>My.Resources</CustomToolNamespace>
    <SubType>Designer</SubType>
    </EmbeddedResource>
    </ItemGroup>
    <ItemGroup>
    <None Include="My Project\Application.myapp">
    <Generator>MyApplicationCodeGenerator</Generator>
    <LastGenOutput>Application.Designer.vb</LastGenOutput>
    </None>
    <None Include="My Project\Settings.settings">
    <Generator>SettingsSingleFileGenerator</Generator>
    <CustomToolNamespace>My</CustomToolNamespace>
    <LastGenOutput>Settings.Designer.vb</LastGenOutput>
    </None>
    </ItemGroup>
    <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
    <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
    Other similar extension points exist, see Microsoft.Common.targets.
    <Target Name="BeforeBuild">
    </Target>
    <Target Name="AfterBuild">
    </Target>
    -->
    </Project>
    add the highlighted part (in notepad) + save the .vbproj file

  17. #17
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    Okay, I had already added an Imports System.Linq in the module and that sufficed.

    One thing I'll mention for others reading this thread... The node I was wanting to sort I was referencing by name, as in oTopNotificationNode.Nodes(oNodeName)... Although this returns a single node, the system thought it was returning a Nodes collection, thus it wouldn't sort.

    For better or worse, I dimensioned a TreeNode and used DirectCast to cast the named node to the TreeNode.

    This worked and I could then sort the node. Finally.

    THANK YOU! You Rock .paul., and have made my day... in fact, my week. Off to rate. Thanks Again. Enjoy your weekend!

  18. #18
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    23,223

    Re: sort only a specific node in a treeview

    oTopNotificationNode.Nodes(oNodeName) returns a treenode
    oTopNotificationNode.Nodes(oNodeName).nodes returns a treenodecollection consisting of the child nodes of oTopNotificationNode.Nodes(oNodeName)

  19. #19
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    Nevermind. I got it. I needed:

    oTopLevelNotificationFolderNode.Nodes(sDispositionName).Nodes.sort(sortOrder.ascending)

    not...

    oTopLevelNotificationFolderNode.Nodes(sDispositionName).sort(sortOrder.ascending)
    Last edited by Dawg; Feb 5th, 2011 at 03:19 PM.

  20. #20
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    I'm now developing an intranet version of my app using VB2010 and ASP 4.0.

    Would this same approach work for a Web Control TreeNode?

    If so, what would be the equivalent file type for the Extensions.vb file? I don't see Module available when inserting New Items in my project, and the code inserted in a web form produces an error at <System.Runtime.CompilerServices.Extension()> saying extension methods can be defined only in modules.

    AddRange also isn't a member of the WebControls.TreeNodeCollection.

    I know this is a long shot but I'm hoping...


  21. #21
    PowerPoster VBDT's Avatar
    Join Date
    Sep 2005
    Location
    CA - USA
    Posts
    2,922

    Re: sort only a specific node in a treeview

    This tread is almost 3 years old

    Dawg, yes the same approach would work for a TreeView web control. The only difference is that web control TreeNode collection doesn't have AddRange method so you should use For Each loop to add the nodes. Take a look on the Code Templates, there you have the Module template. Everything else is the same.

  22. #22
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    Hmm, I have no Module template when selecting New --> Item for my Web Application.

    When I add my existing functional Module via Add Existing Item, it comes in, and once I replace AddRange with a For Each loop it's happy.

    The problem is it gives me no sort method for my nodes. In fact my application doesn't seem to recognize the Module at all because if I put a very simple [Public Function TESTTEST() as boolean] in it, that function doesn't show up as available in my other Web Forms.

    Which brings the next question to mind, in addition to the sort functionality - where do you put subs and functions you want available to the entire project in a Web Application? Off topic but... maybe someone else is facing the same question.

  23. #23
    PowerPoster VBDT's Avatar
    Join Date
    Sep 2005
    Location
    CA - USA
    Posts
    2,922

    Re: sort only a specific node in a treeview

    Quote Originally Posted by Dawg View Post
    Hmm, I have no Module template when selecting New --> Item for my Web Application.

    When I add my existing functional Module via Add Existing Item, it comes in, and once I replace AddRange with a For Each loop it's happy.

    The problem is it gives me no sort method for my nodes. In fact my application doesn't seem to recognize the Module at all because if I put a very simple [Public Function TESTTEST() as boolean] in it, that function doesn't show up as available in my other Web Forms.

    Which brings the next question to mind, in addition to the sort functionality - where do you put subs and functions you want available to the entire project in a Web Application? Off topic but... maybe someone else is facing the same question.
    Right click on the WebApplication in the solution window -> Add -> New Item. Rest is shown in the image below.

    Here is the content of the Module.
    vb Code:
    1. Module Extensions
    2.     Public Enum sortOrder
    3.         ascending
    4.         descending
    5.     End Enum
    6.  
    7.     <System.Runtime.CompilerServices.Extension()> _
    8.     Public Sub sort(ByVal instance As TreeNodeCollection, ByVal order As sortOrder)
    9.         Dim nodes() As TreeNode = instance.Cast(Of TreeNode).ToArray
    10.         Array.Sort(nodes, Function(x As TreeNode, y As TreeNode) If(order = sortOrder.ascending, x.Text.CompareTo(y.Text), y.Text.CompareTo(x.Text)))
    11.         instance.Clear()
    12.         For Each n As TreeNode In nodes
    13.             instance.Add(n)
    14.         Next
    15.     End Sub
    16. End Module

    And this is how you use it:
    vb Code:
    1. Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    2.     Me.TreeView1.Nodes(0).ChildNodes.sort(sortOrder.ascending)
    3. End Sub
    Attached Images Attached Images  

  24. #24
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    Aside from the Module issues - I got something working. Worst case this code can manually be used whenever one needs to sort the ChildNodes of a TreeNode.

    I'm still curious about public subs and functions in a Web application, but that's probably another thread.

    Code:
            
    Dim nodes() As TreeNode = oMyNode.ChildNodes.Cast(Of TreeNode).ToArray
    Array.Sort(nodes, Function(x As TreeNode, y As TreeNode) x.Text.CompareTo(y.Text))
    oMyNode.ChildNodes.Clear()
    For Each oNode As TreeNode In nodes
        oMyNode.ChildNodes.Add(oNode)
    Next

  25. #25
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    I think the difference is I did File, New Website, as opposed to File, New Project, ASP.NET Web Application. My apologies for previously calling it a Web Application - apparently it's not.

    The book I'm reading claims they are synonomous, however I don't have an Insert, New Item, Module... and if I manually insert one (it's just a .vb file), it's not visible to the rest of my Web Forms.

    I'm good tho - all part of the learning experience, and I appreciate the help .
    Attached Images Attached Images  

  26. #26
    PowerPoster VBDT's Avatar
    Join Date
    Sep 2005
    Location
    CA - USA
    Posts
    2,922

    Re: sort only a specific node in a treeview

    Yes, the module template doesn't exist in web site project but you can still have it. What you need to do is to add the existing module file to the App_Code folder and add the "Public" key word in front of the module. Here is the module code:
    vb Code:
    1. Imports Microsoft.VisualBasic
    2.  
    3. Public Module Extensions
    4.     Public Enum sortOrder
    5.         Ascending = 0
    6.         Descending = 1
    7.     End Enum
    8.  
    9.     <System.Runtime.CompilerServices.Extension()> _
    10.     Public Sub sort(ByVal instance As TreeNodeCollection, ByVal order As sortOrder)
    11.         Dim nodes() As TreeNode = instance.Cast(Of TreeNode).ToArray
    12.         Array.Sort(nodes, Function(x As TreeNode, y As TreeNode) If(order = sortOrder.ascending, x.Text.CompareTo(y.Text), y.Text.CompareTo(x.Text)))
    13.         instance.Clear()
    14.         For Each n As TreeNode In nodes
    15.             instance.Add(n)
    16.         Next
    17.     End Sub
    18. End Module
    Attached Images Attached Images  

  27. #27
    Junior Member Dawg's Avatar
    Join Date
    Nov 2009
    Location
    Portland Or, USA
    Posts
    26

    Re: sort only a specific node in a treeview

    Works Beautifully!

    THANK YOU (and yes I said it another way too)!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width