Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


VB. Net Collections and the Key !!!

Posted on 2004-09-23
Medium Priority
Last Modified: 2007-12-19
Hello All,

I'm having some smal problems with a collection in VB .Net .....

Public Class Reports

    Inherits CollectionBase
    Public Sub New()
    End Sub

    Public Function Add(ByVal objNewItem As Report) As Report


        Return objNewItem
    End Function

    Default Public Property Item(ByVal iIndex As Integer) As Report
            Return MyBase.InnerList.Item(iIndex)
        End Get
        Set(ByVal ReportObjectToBeAdded As Report)
            MyBase.InnerList.Item(iIndex) = ReportObjectToBeAdded
        End Set
    End Property

    Public Sub Remove(ByVal iIndex)
    End Sub

End Class

I know there isn't much going on here, but i just wanted to illustrate what i mean.

In VB 6.0 you could add a key (i think, it might have been called an index), when you are adding an item to a collection, and then from then on you could retrieve that object from the collection by using that Key. (Although you couldn't retrieve the key once it has been set).

This line MyBase.InnerList.Add(objNewItem) does return a index, which i think is the same thing, but i want to be able to set it ??

Is this possible ?? or have i got the whole thing upside down ??

Thanks in Advance.

Question by:DavidWilkinson
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
LVL 19

Expert Comment

ID: 12136065
If you want a user-definable value rather than a sequential index value as a key, then try deriving from DictionaryBase instead of CollectionBase.  The dictionary functionality gives you the ability to define a key (not necessarily numeric) for each value.  You then look up the values by their keys.  You lose the ability to say "Get me the third element" though.  You can use an enumerator to iterate sequentially through the values or you can look them up by the key values you gave them.  You'd have to do a totally custom collection to get both user-key AND sequential random access.
LVL 86

Accepted Solution

Mike Tomlinson earned 500 total points
ID: 12136090
Hi DavidWilkinson,

The index is not the same as the key.  The index is the position of your item in the collection.  This can possibly change however, as you remove items from your collection and the items get shifted down to fill the gap left behind.

The key is string associated with your item that can be used to quickly retrieve that item regardless of its current position in the collection.

But why are you reinventing the wheel?  The Collection object from VB6 still exists in VB.Net:

    Dim Reports As Collection = New Collection
    Reports.Add("item1", "key1") ' You can add your instances of Report instead

>> Although you couldn't retrieve the key once it has been set

It is common practice to store the key in item itself.  Create a variable inside your Report class to the hold the key so you can easily use it.

If you need a more robust collection object, then comsider using the HashTable already built into .Net.  It works similarly to a Collection in that it has key/value pairs but it is much more powerful.  It works only on key values however.  You cannot access the items by index.  The HashTable has two very convient functions called ContainsKey() and ContainsValue() though that I use often.



Author Comment

ID: 12136665
Hi Idle_Mind,

Many thanks for your super-quick respone.

As i'm sure you guessed, I'm quite experianced with VB 6.0 and have only started to look at VB .Net, mainly becuase i'm developing a flexible end-user Crystal Reports Viewer (and possibly designer) and i want to use the Dataset with ADO .Net.

If you have time, could you give be a brief description (possibly a example) of the HashTable, this is the first i've heard of it, and i'm intrigued ;o)

I'm going to Accept your answer, but to be honest I haven't asked many questions on Experts Exchange, so i might cock it up.

Thanks your your time.

Kind Regards


PS Thanks for your answer aslo drichards.


Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Author Comment

ID: 12136975
I don't know if i'm allowed to do this once i've accepted an answer, but ......

Using the Collection object as Idle_Mind suggested, i can't do the For Each objLemon in objLemons (outside the actual class).

In VB 6 there was the NewEnum which you had to set the process ID to -4 etc

is there any similar function in VB .net

Kind Regards

LVL 86

Expert Comment

by:Mike Tomlinson
ID: 12137512
You have to implement the IEnumerable interface as shown below and then you can use your class in a For Each...Next statement:

Public Class Lemons
    Implements IEnumerable

    Private myCollection As Collection = New Collection

    Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return myCollection.GetEnumerator
    End Function

    Public ReadOnly Property count() As Integer
            Return myCollection.Count
        End Get
    End Property

    Public Sub add(ByRef Item As Object, Optional ByVal key As String = Nothing, _
        Optional ByVal before As Object = Nothing, Optional ByVal after As Object = Nothing)
        myCollection.Add(Item, key, before, after)
    End Sub

    Public Sub remove(ByVal key As String)
    End Sub

    Public Sub remove(ByVal index As Integer)
    End Sub

    Public ReadOnly Property item(ByVal key As String) As Object
            Return myCollection.Item(key)
        End Get
    End Property

    Public ReadOnly Property item(ByVal index As Integer) As Object
            Return myCollection.Item(index)
        End Get
    End Property

End Class
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 12137609
Here is a very simple example of using a HashTable.  In this case, we are only using strings, but you can use object as the key or the value:

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()

        'This call is required by the Windows Form Designer.

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
            End If
        End If
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents NumericUpDown1 As System.Windows.Forms.NumericUpDown
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label
        Me.NumericUpDown1 = New System.Windows.Forms.NumericUpDown
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.ListBox1 = New System.Windows.Forms.ListBox
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.Label1.Location = New System.Drawing.Point(56, 8)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(224, 24)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "Label1"
        Me.NumericUpDown1.Location = New System.Drawing.Point(8, 8)
        Me.NumericUpDown1.Name = "NumericUpDown1"
        Me.NumericUpDown1.Size = New System.Drawing.Size(40, 20)
        Me.NumericUpDown1.TabIndex = 1
        Me.Button1.Location = New System.Drawing.Point(8, 40)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(88, 32)
        Me.Button1.TabIndex = 2
        Me.Button1.Text = "List Keys"
        Me.Button2.Location = New System.Drawing.Point(8, 80)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(88, 32)
        Me.Button2.TabIndex = 3
        Me.Button2.Text = "List Values"
        Me.ListBox1.Location = New System.Drawing.Point(104, 40)
        Me.ListBox1.Name = "ListBox1"
        Me.ListBox1.Size = New System.Drawing.Size(176, 212)
        Me.ListBox1.TabIndex = 4
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()

    End Sub

#End Region

    Private myHash As Hashtable = New Hashtable

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim i As Integer
        Dim numEntries As Integer = 5

        For i = 1 To numEntries
            myHash.Add("Key" & i, "Item" & i)
        NumericUpDown1.Minimum = 1
        NumericUpDown1.Maximum = numEntries * 2
    End Sub

    Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
        Dim key As String
        key = "Key" & NumericUpDown1.Value
        If myHash.ContainsKey(key) Then
            Label1.Text = myHash.Item(key)
            Label1.Text = "(No Such Key)"
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim key As String

        For Each key In myHash.Keys
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim value As String

        For Each value In myHash.Values
    End Sub

End Class

Featured Post

Tech or Treat!

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Introduction to Processes

596 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question