Solved

An arrayList of arrayLists VB.NET

Posted on 2004-09-01
9
2,744 Views
Last Modified: 2008-01-09
I have an arrayList in which I put objects (objects containing some connected lines and a pen)
then I draw all the objects from the arrayList.
Now, I want to make an arraylist of arrayLists (every curve with 400 connected lines is in an arrayList)
This way I would be able to draw any specific curve I wish, instead of drawing them all.
Notice that both the ArrayList and the collection of arrayLists need to be dynamic(so I can add to it)
Any idea?
Here is my idea:

Public Curves As ArrayList

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

Dim ACurveObject As New ArrayList
ACurveObject.Add(New LineObject(New Point(x1, y1), New Point(x2, y2)))
Curves.Add(ACurveObject)

End Sub
0
Comment
Question by:kouroshparsa
[X]
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
  • 6
  • 3
9 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 11960151
There is nothing wrong with having an ArrayList of ArrayLists but...

From an OOP perspective though, I think it would make more sense to create a Class called "Curve" to encapsulate an ArrayList containing your 400 LineObjects.  You could add an ID or CurveName property to the class to give each instance a unique identifier.

Then I would use a HashTable to store all the instances of your Curve class.  You can use the unique identifier of each Curve instance as the key value for adding into the HashTable.  This way you can easily retrieve any specific curve you need without looping through an ArrayList.

My free two cents,

Idle_Mind
0
 
LVL 2

Author Comment

by:kouroshparsa
ID: 11960464
Enev though it is not essencial, I simply want to categorize the ArrayList. I'm not sure about the key parameter of HashTable. I hope a HashTable can hold ArrayLists.
I like the idea of making a class called "Curve"  obvously you do not mean having a class in the module (because when making a new forms, they all refer to the same curves)

I made the class, but I've never made a property that would return an arrayList with a key??. All I tried failed since I don't know about the key or what you call ID.
You are more than welcome to comment.
I increased the points...if you think this question is still worth more, let me know.
Regard, Kourosh
0
 
LVL 2

Author Comment

by:kouroshparsa
ID: 11978623
Idle_Mind:"There is nothing wrong with having an ArrayList of ArrayLists"
Well, technically I am not sure, since an ArrayList is a collection type but you can add objects to an ArrayList.
I think I am very close to solving this. I have a class with a Read-Only property.
Would you copy paste and see the single problem:
'===Module:
Module Module1
    Public Interface GraphObject
        Sub Paint(ByRef g As Graphics)
    End Interface

    Public Class LineObject
        Implements GraphObject

        Private pointA As Point
        Private pointB As Point

        Public Sub New(ByVal ptA As Point, ByVal ptB As Point)
            pointA = ptA
            pointB = ptB
        End Sub

        Public Sub Paint(ByRef g As Graphics) Implements GraphObject.Paint
            g.DrawLine(Pens.Black, pointA, pointB)
        End Sub
    End Class
End Module
'=======Form1:
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 Button1 As System.Windows.Forms.Button
    Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
    Friend WithEvents CheckedListBox1 As System.Windows.Forms.CheckedListBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.PictureBox1 = New System.Windows.Forms.PictureBox
        Me.CheckedListBox1 = New System.Windows.Forms.CheckedListBox
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(16, 304)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(120, 72)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Make a new collection of lines collection containing 100 objects in each"
        '
        'PictureBox1
        '
        Me.PictureBox1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.PictureBox1.BackColor = System.Drawing.Color.White
        Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox1.Location = New System.Drawing.Point(24, 16)
        Me.PictureBox1.Name = "PictureBox1"
        Me.PictureBox1.Size = New System.Drawing.Size(528, 272)
        Me.PictureBox1.TabIndex = 1
        Me.PictureBox1.TabStop = False
        '
        'CheckedListBox1
        '
        Me.CheckedListBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.CheckedListBox1.CheckOnClick = True
        Me.CheckedListBox1.Location = New System.Drawing.Point(144, 304)
        Me.CheckedListBox1.Name = "CheckedListBox1"
        Me.CheckedListBox1.Size = New System.Drawing.Size(400, 92)
        Me.CheckedListBox1.TabIndex = 2
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(560, 414)
        Me.Controls.Add(Me.CheckedListBox1)
        Me.Controls.Add(Me.PictureBox1)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Curves As ClassCurves
    Private rnd As New Random(DateTime.Now().Second)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ACurveObject As New ArrayList

        Dim x1, y1, x2, y2 As Integer
        For num As Short = 1 To 100
            x1 = rnd.NextDouble() * PictureBox1.Width
            y1 = rnd.NextDouble() * PictureBox1.Height
            x2 = rnd.NextDouble() * PictureBox1.Width
            y2 = rnd.NextDouble() * PictureBox1.Height
            Dim ln As New LineObject(New Point(x1, y1), New Point(x2, y2))
            ACurveObject.Add(ln)
        Next num

        Curves.CollectionOfCurves.Add(ACurveObject)
        CheckedListBox1.Items.Add("Curve#" & Curves.CollectionOfCurves.Count, CheckState.Checked)
        PictureBox1.Refresh()
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim go As Object
        Dim SelectedCurvesArray(CheckedListBox1.Items.Count - 1) As Short
        Dim indArr = 0
        For num As Short = 0 To CheckedListBox1.Items.Count - 1
            If CheckedListBox1.Items.Item(num).ischecked Then
                SelectedCurvesArray(indArr) = num
                indArr += 1
            End If
        Next

        Dim ind As Short
        For Each ind In SelectedCurvesArray
            For Each go In Curves.CollectionOfCurves.Item(ind)
                go.paint(e.Graphics)
            Next
        Next

    End Sub
End Class
'=======ClassCurves:
Public Class ClassCurves
    Private CurvesCollection As ArrayList
    Public ReadOnly Property CollectionOfCurves() As ArrayList
        Get
            Return CurvesCollection
        End Get
    End Property
End Class
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 150 total points
ID: 11978993
Try this out...

Regards,

{pseudocode} / {Time} ± ¼*ƒ(Me.Thoughts÷3)^² = Idle »(°_°)« Mind

' -----------------------------------------------------------------------
' Module1
' -----------------------------------------------------------------------
Module Module1

    Public Interface GraphObject
        Sub Paint(ByRef g As Graphics)
    End Interface

    Public Class LineObject
        Implements GraphObject

        Private pointA As Point
        Private pointB As Point

        Public Sub New(ByVal ptA As Point, ByVal ptB As Point)
            pointA = ptA
            pointB = ptB
        End Sub

        Public Sub Paint(ByRef g As Graphics) Implements GraphObject.Paint
            g.DrawLine(Pens.Black, pointA, pointB)
        End Sub
    End Class

    Public Class ClassCurves
        Implements GraphObject

        Public ID As String
        Public CurvesCollection As ArrayList = New ArrayList

        Public Overrides Function toString() As String
            Return "Curve #" & ID
        End Function

        Public Sub Paint(ByRef g As System.Drawing.Graphics) Implements GraphObject.Paint
            Dim lo As LineObject

            For Each lo In CurvesCollection
                lo.Paint(g)
            Next
        End Sub
    End Class

End Module

' -----------------------------------------------------------------------
' Form1
' -----------------------------------------------------------------------
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 Button1 As System.Windows.Forms.Button
    Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
    Friend WithEvents CheckedListBox1 As System.Windows.Forms.CheckedListBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.PictureBox1 = New System.Windows.Forms.PictureBox
        Me.CheckedListBox1 = New System.Windows.Forms.CheckedListBox
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.Button1.Location = New System.Drawing.Point(16, 272)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(120, 72)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Make a new collection of lines collection containing 100 objects in each"
        '
        'PictureBox1
        '
        Me.PictureBox1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.PictureBox1.BackColor = System.Drawing.Color.White
        Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox1.Location = New System.Drawing.Point(24, 16)
        Me.PictureBox1.Name = "PictureBox1"
        Me.PictureBox1.Size = New System.Drawing.Size(552, 240)
        Me.PictureBox1.TabIndex = 1
        Me.PictureBox1.TabStop = False
        '
        'CheckedListBox1
        '
        Me.CheckedListBox1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.CheckedListBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.CheckedListBox1.CheckOnClick = True
        Me.CheckedListBox1.Location = New System.Drawing.Point(144, 272)
        Me.CheckedListBox1.Name = "CheckedListBox1"
        Me.CheckedListBox1.Size = New System.Drawing.Size(424, 92)
        Me.CheckedListBox1.TabIndex = 2
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(584, 382)
        Me.Controls.Add(Me.CheckedListBox1)
        Me.Controls.Add(Me.PictureBox1)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private rnd As New Random(DateTime.Now().Second)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim curve As ClassCurves = New ClassCurves
        curve.ID = CheckedListBox1.Items.Count + 1

        Dim x1, y1, x2, y2 As Integer
        For num As Short = 1 To 100
            x1 = rnd.NextDouble() * PictureBox1.Width
            y1 = rnd.NextDouble() * PictureBox1.Height
            x2 = rnd.NextDouble() * PictureBox1.Width
            y2 = rnd.NextDouble() * PictureBox1.Height
            curve.CurvesCollection.Add(New LineObject(New Point(x1, y1), New Point(x2, y2)))
        Next num

        CheckedListBox1.Items.Add(curve, CheckState.Checked)
        PictureBox1.Refresh()
    End Sub

    Private Sub CheckedListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckedListBox1.SelectedIndexChanged
        PictureBox1.Refresh()
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim go As GraphObject

        e.Graphics.Clear(PictureBox1.BackColor)
        For Each go In CheckedListBox1.CheckedItems
            go.Paint(e.Graphics)
        Next
    End Sub

End Class
0
 
LVL 2

Author Comment

by:kouroshparsa
ID: 11982090
Excellent.
I thought that if I use a class in the module _like you did_ when I have different instances (copies) of the form, they would all refer to one collection (meaning that several applications would display the same curves)...But that is not true, which is gooooooooood.
I still do not know what went wrong with my previous code...?

Thanks a lot.
                        ^ ^
                        +  +
                    [     |    ]
                       \==/

Regards.
0
 
LVL 2

Author Comment

by:kouroshparsa
ID: 11982712
Oops. I noticed the collection will be erased? If you put the following in a button_Sub click and click the button after drawing, it displays 0.
        Dim curves As New ClassCurves
        MsgBox(CStr(curves.CurvesCollection.Count))
I think that your code actually stores the arrayList in the CheckedListBox. Is that so???
So there is only one temporary collection !
Since I'm using a different form for CheckedListBox, I lose the collection because I hide the form that contians the checkedListBox; so, it is erased when it is hidden.

Would you explain why the objects of a CheckedListBox are erased when it is hidden ?
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 11984274
You can keep your ClassCurves instances in a Hashtable instead of the CheckedListBox as shown below.  Then you can pass a reference to the HashTable to other forms so you can build the CheckedListBox based on the key values.

Idle_Mind

Public Class Form1
    Inherits System.Windows.Forms.Form

' #Region " Windows Form Designer generated code "

    Private rnd As New Random(DateTime.Now().Second)
    Private curves As New Hashtable

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim curve As ClassCurves = New ClassCurves
        curve.ID = CheckedListBox1.Items.Count + 1

        Dim x1, y1, x2, y2 As Integer
        For num As Short = 1 To 100
            x1 = rnd.NextDouble() * PictureBox1.Width
            y1 = rnd.NextDouble() * PictureBox1.Height
            x2 = rnd.NextDouble() * PictureBox1.Width
            y2 = rnd.NextDouble() * PictureBox1.Height
            curve.CurvesCollection.Add(New LineObject(New Point(x1, y1), New Point(x2, y2)))
        Next num

        curves.Add(curve.ToString, curve)
        CheckedListBox1.Items.Add(curve.ToString, CheckState.Checked)
        PictureBox1.Refresh()
    End Sub

    Private Sub CheckedListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckedListBox1.SelectedIndexChanged
        PictureBox1.Refresh()
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim curveName As String
        Dim go As GraphObject

        e.Graphics.Clear(PictureBox1.BackColor)
        For Each curveName In CheckedListBox1.CheckedItems
            go = curves.Item(curveName)
            go.Paint(e.Graphics)
        Next
    End Sub

End Class
0
 
LVL 2

Author Comment

by:kouroshparsa
ID: 11986058
Hello Idle_Mind.
Thanks a lot.
With your example, I understood the usage of Hushtables and writing Overridable methods. That is a perfect usage...
Regards, kourosh
0
 
LVL 2

Author Comment

by:kouroshparsa
ID: 11986300
Hi Idle-Mind. Again the listBox was erased, but I found the real bug.  I used to "Hide" the form containing the checkedListBox. That is the bug !!!!
I fixed the bug by changing "form1.hide" to "form1.visible=False"

I'd read a book about vb.Net it said "hide and visible=False are essentailly the same"
but that's not true !
In any case, your HashTable idea is valuable to me !

Have fun.
Regards, Kourosh.

                  ****    ****    *     I'm not as "think" as you "drunk" I am !
                  *    ****    ****
0

Featured Post

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

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

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

732 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