I'm having problems with this SearchButton
code in VB (Visual Studio 2012):
This code in Form1.VB:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim results As Artist
results = Array.SearchArray(artistArray(), SearchTextBox.Text)
End Sub
and I'm getting an error that artistArray
is inaccessible due to its protection level.
I'm new to VB, so I'm sure it's something I'm doing wrong, but I can't find it.
I have checked spelling, visibility (Public
), and so on.
array.vb at the moment:
Public Class Array
Public artistArray() As Artist
Public searchResults(artistArray.Length) As Artist
Dim searchString As String
Public Function SearchArray(ByVal artistArray(), searchString) As Artist()
Dim x As Integer ' artist index variable for loop
Dim index As Integer = 0 ' index for results
For x = 0 To artistArray.GetUpperBound(0)
Dim temp As Artist = artistArray(x)
If temp.Name.ToLower().Contains(searchString.ToLower()) Then
searchResults(index) = artistArray(x) ' if search hit then add current item to result array
index += 1 ' and incr. result index
End If
Next
ReDim Preserve searchResults(index)
Return searchResults
End Function
' ...
End Class
Public
is not the same as global. In fact, VB.NET doesn't even support Global
variables, in the strict old VB6 sense. Even though it's Public
, it's still scoped to the Array
class, so you have to access if as a property of that class. However, it's also an instance property, which means it's a member of each Array
object (i.e. instance), not of the class, itself, for instance:
Dim first As Artist = Array.artistArray(0) ' Does not work
But:
Dim a As New Array()
Dim first As Artist = a.artistArray(0) ' Works
If you want to make it a shared property, meaning it will be a member of the class, itself, rather than each instance of that class, and therefore, effectively global, you need to add the Shared
keyword, like this:
Public Class Array
Public Shared arrayArtist() As Artist
' ...
End Class
Then, you will be able to access it from anywhere in your project, like this:
Dim first As Artist = Array.artistArray(0) ' Works now
Of course, having global variables is almost always a bad design decision, but that's another topic.
All of this is a bit confusing too, because you are calling your class Array
. Technically, you can do that if you really want to, but I wouldn't advise it since the .NET Framework already includes a class called Array
which is pretty fundamental.
Also, there's no reason to store the search results in a field of the class. It would be far better if that was scoped to be local to the search method. And it would be simpler if you used a For Each
loop and a List
, like this:
Public Class ArtistBusiness
Public Shared Artists() As Artist
Public Shared Function SearchArtists(artists() As Artist, searchString As String) As Artist()
Dim results As New List(Of Artist)()
For Each i As Artist In artists
If i.Name.IndexOf(searchString, StringComparison.CurrentCultureIgnoreCase) >=0 Then
results.Add(i)
End If
Next
Return results.ToArray()
End Function
End Class
Then, you could call it like this:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim results() As Artist
results = ArtistBusiness.SearchArtists(ArtistBusiness.Artists, SearchTextBox.Text)
End Sub
It pains me to even put globals in my example, but there it is. Notice I changed the ToLower.Contains
to IndexOf
, since that is safer, given certain culture issues. I also changed the results
variable in the click event handler to an array, since that is what the method is returning.
You can also simplify the code even more by using LINQ, like this:
Public Shared Function SearchArtists(artists() As Artist, searchString As String) As Artist()
artists.Select(Function(x) x.Name.IndexOf(searchString, StringComparison.CurrentCultureIgnoreCase) >= 0).ToArray()
End Function
But I would advise you to spend more time learning the fundamentals before you start trying to do anything fancy, like that.
Your whole code can be replaced by a single LINQ
line
Public artists As Artist()
Public Function FindArtists(searchString As String) As Artist()
Return artists.Where(Function(a) a.Name.ToLower().Contains(searchString)).ToArray()
End Function