Link to home
Start Free TrialLog in
Avatar of DavidWilkinson
DavidWilkinson

asked on

VB. Net Collections and the Key !!!

Hello All,

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

Public Class Reports

    Inherits CollectionBase
    Public Sub New()
        MyBase.New()
    End Sub

    Public Function Add(ByVal objNewItem As Report) As Report

        MyBase.InnerList.Add(objNewItem)

        Return objNewItem
    End Function

    Default Public Property Item(ByVal iIndex As Integer) As Report
        Get
            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)
        MyBase.InnerList.Remove(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.

Dave
Avatar of drichards
drichards

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.
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DavidWilkinson

ASKER

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

DavidWilkinson

PS Thanks for your answer aslo drichards.

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

DavidWilkinson
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
        Get
            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)
        myCollection.Remove(key)
    End Sub

    Public Sub remove(ByVal index As Integer)
        myCollection.Remove(index)
    End Sub

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

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

End Class
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()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        '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
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    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.SuspendLayout()
        '
        'Label1
        '
        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"
        '
        'NumericUpDown1
        '
        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
        '
        'Button1
        '
        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"
        '
        'Button2
        '
        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"
        '
        'ListBox1
        '
        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
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.Add(Me.ListBox1)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.NumericUpDown1)
        Me.Controls.Add(Me.Label1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    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)
        Next
        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)
        Else
            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

        ListBox1.Items.Clear()
        For Each key In myHash.Keys
            ListBox1.Items.Add(key)
        Next
    End Sub

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

        ListBox1.Items.Clear()
        For Each value In myHash.Values
            ListBox1.Items.Add(value)
        Next
    End Sub

End Class