Solved

VB. Net Collections and the Key !!!

Posted on 2004-09-23
6
12,086 Views
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()
        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
0
Comment
Question by:DavidWilkinson
  • 3
  • 2
6 Comments
 
LVL 19

Expert Comment

by:drichards
Comment Utility
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.
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 125 total points
Comment Utility
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.

Regards,

Idle_Mind
0
 

Author Comment

by:DavidWilkinson
Comment Utility
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.

0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:DavidWilkinson
Comment Utility
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
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
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.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

728 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now