Click here to Skip to main content
15,886,963 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a project where I collect plays for a game, and store the details of the play in a listbox /collection. Later, I want to be able to obtain the last play and reverse it, then delete it from the listbox / collection.

My problem is the delete of the listbox works, but the delete of the collection does not work.

Attached is an abbreviated version of the project.

What am I doing wrong?

What I have tried:

The form contains a listbox (ListEntries), two buttons (btnAdd and bthUndo), and a textbox (TxtDisplay)

btnAdd adds a generated entry to the listbox and collection, then displays the result in the textbox.

Each time it is clicked, it adds another entry to the listbox / collection.

btnUndo is supposed to return the LAST entry in the collection, display it, then delete it from the listbox and the collection. Each time it is clicked, it should delete the last entry in the list.

The problem is that the “return” always returns the LAST entry added – period. The listbox entry is deleted, but it appears the collection entry is never deleted. What am I doing wrong.

Class to contain details of each play.
VB.NET
Public Class CEntry
    Public EntrySeq As Integer
    Public EntryTxt As String

    Public Sub add()
        EntrySeq = 0
        EntryTxt = ""
    End Sub

    Public Overrides Function ToString() As String
        Dim display As String
        display = "Play=" + EntrySeq.ToString("D2") +
                 "  EntryText=" + EntryTxt
        Return display
    End Function
End Class

Class to contain collection of plays.
VB.NET
Public Class CCollect
    Inherits CollectionBase

    ' Add a entry to the collection
    Public Sub add(ByRef newentry As CEntry)
        Me.List.Add(newentry)
    End Sub
End Class

Form1 Routines
VB.NET
Public Class Form1

    Dim AddCount As Integer
    Dim SelectIndex As Integer
    Dim SelectSub As Integer

    Dim Entry As New CEntry
    Dim Collect As New CCollect

    Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
        AddCount += 1
        Entry.EntrySeq = AddCount
        Entry.EntryTxt = "S" + AddCount.ToString("D2")

        'Add the new entry to the Collection
        Collect.add(Entry)
        'add the entry to the listbox
        SelectIndex = ListEntries.Items.Add(Entry)

        TxtDisplay.Text = "Count=" + Collect.Count.ToString("D2") +
            "  Entry=" + Entry.ToString
    End Sub

    Private Sub bthUndo_Click(sender As Object, e As EventArgs) 
Handles bthUndo.Click

        Dim testSelection As New CEntry
        Dim SelectIndex As Integer
        Dim SelectSub As Integer

        SelectSub = Collect.Count          ' Range 1 thru count
        SelectIndex = SelectSub - 1        ' range 0 thru count - 1

        If SelectSub = 0 Then
            Exit Sub
        End If
        testSelection = Nothing
        testSelection = Collect(SelectIndex)

        TxtDisplay.Text = "Count=" + SelectSub.ToString("D2") +
                          "  Entry=" + testSelection.ToString

        ' Remove Selection from ListBox
        ' SelectIndex is in the 0 to count-1 range
        ListEntries.Items.RemoveAt(SelectIndex)

        'Remove Selection from Collection
        Collect.RemoveAt(SelectIndex)

    End Sub
End Class
Posted
Updated 29-Aug-23 3:46am
v3

btnUndo doesn't "return" anything - like all event handler methods it is a void method - it cannot return any value at all.

So the problem very likely isn't that it is not removing the last element from the actual collection - RemoveAt isn't overridable so the default method is always called and that does exactly what it is supposed to. The problem is that your code always displays the last element before you remove it which probably makes it look like the remove isn't working.

Use the debugger to examine the collection and you'll see what is going on a lot more clearly.
 
Share this answer
 
Comments
Member 12602897 29-Aug-23 10:57am    
The return info is in the display field on the form. Each time the btnUndo is clicked it should display the last entry in the collection, then delete/remove that last entry. The next time it is clicked it should show a different / previous last entry. It does not!

I have tried displaying the individual entries from the collection instead of using the "tostring" override, with the same results. I don't know how to look at the data within the collection class itself without accessing an entry and looking at the individual fields in the entry class. Every time I access what should be the last entry in the collection class it appears to be the same data as the original last entry.
OriginalGriff 29-Aug-23 11:35am    
So what does the debugger show you is happening?
Member 12602897 29-Aug-23 13:51pm    
For the add process an entry is added each time the button is clicked, each entry with a sequential number to make them all different. Teh debugger shows those fields as they are added.

Within the Undo process each time the button is clicked the debugger shows the return for the count of entries in the collection has been correctly decremented, but the data returned for the index (count - 1) is always the same last entry, even though that entry should have been deleted. The debugger shows that the items returned have the data from the last entry that had been added to the collection.
Member 12602897 29-Aug-23 17:59pm    
In playing with it, I find that when I delete/undo an entry, then add another one, the entry count is the correct number (minus one - plus one). So the process of adding entries and deleting them is working correctly. The problem is that when returning the last entry it only returns the last ADDED one, no matter how many are deleted. It seems I am getting a left-over entry from the add process from somewhere, but not the one at the end of the collection.
I made some modifikations to your ButtonAdd-method :
VB
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
    AddCount += 1
    Dim myEntry As New CEntry
    myEntry.EntrySeq = AddCount
    myEntry.EntryTxt = "S" + AddCount.ToString("D2")

    'Add the new entry to the Collection
    Collect.add(myEntry)
    'add the entry to the listbox
    SelectIndex = ListEntries.Items.Add(myEntry)

    txtDisplay.Text = "Count=" + Collect.Count.ToString("D2") +
        "  Entry=" + myEntry.ToString
End Sub


now it should work.
your mistake was that you are adding the whole time the same Entry to your Collection. So, if you debug it, you see as many counts you have, allways only the last added Entry for each Item.
in my method I create at first a new Entry and add this to the Collection ...
 
Share this answer
 
v2
Comments
Member 12602897 30-Aug-23 10:46am    
Thank you, thank you, thank you - I was going crazy trying everything but missed that one.
Ralf Meier 30-Aug-23 12:18pm    
you are welcome ...
please be so kind and rate also the Solution

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900