Looping through your data with for each
Creating an iterable ListBox
As an example use of Iterator and Iterable, you can create a version of the DesktopListBox control that lets you iterate through its rows using For Each...Next. Here's how you can implement it.
Create a new class called ListBoxIterator and assign it the Iterator interface which adds empty MoveNext and Value methods. You'll add code to those in a moment, but first add a Constructor method to ListBoxIterator:
Public Sub Constructor(lb As DesktopListBox) Data = lb InitialListCount = Data.RowCount End Sub
This constructor takes as a parameter a DesktopListBox and saves references to the ListBox and its initial count to properties on the class which you should add now:
Data As DesktopListBox
InitialRowCount As Integer = -1
In addition you'll want one other property to track the current row of the iterator:
IteratorRow As Integer
You'll also want to add a computed property that checks to verify that the ListBox has not been modified while you are iterating through it. The computed property:
IsValid As Boolean
has this code in its Get block:
If InitialRowCount <> Data.RowCount Then Return False Else Return True End If
With these properties in place you can now implement the two interface methods. First, start with MoveNext:
// Ensure ListBox has not been modified while iterating If Not IsValid Then Var exc As New IteratorException exc.Message = "ListBox row count cannot be modified within For...Each loop." Raise exc End If If IteratorRow < (Data.RowCount - 1) Then // Move to the next row in the ListBox. // Note the first row is "-1", so you have to call // MoveNext once to get to the first row 0. IteratorRow = IteratorRow + 1 Return True Else // No more rows in ListBox Return False End If
And now implement the Value method which actually gets the data from the ListBox. You can actually return the data however you want. In the case of a ListBox, this code gets the String value for each column in the row, separates it by spaces, and returns it as a single String value.
Var lbRow As String Var space As String For column As Integer = 0 To Data.LastColumnIndex lbRow = lbRow + space + Data.CellTextAt(IteratorRow, column).ToString space = " " Next Return lbRow
Now that you have created an iterator that can work with a DesktopListBox you need to create a DesktopListBox subclass that uses the iterator. Add a new class (called IterableListBox) and set its super to DesktopListBox and assign it the Iterable interface which adds the GetIterator method. In this method you need to set up and return the iterator you just created. You do that by calling New and passing in the ListBox itself:
Var lbIterator As New ListBoxIterator(Self) Return lbIterator
That is all you need on this subclass. Now you can use the subclass with For Each...Next. On Window1, drag IterableListBox to the layout and add some initial data using the Initial Value property in the Inspector. Now add a button to the Window and put this code in it to iterate through the values you've added to the ListBox:
For Each row As String In IterableListBox1 MessageBox(row) Next
Run your project and click the button where you'll get the contents of the ListBox displayed in a message box, one row at a time.