I need to know how to avoid the System.Data.DataRowview in vb 2010 - vb.net

I have an issue with my code; and would appreciate some assistance getting her to do what I want without an annoying error. Read the databound listbox strings, find the user selected string and write said string to a file.
Private Sub btnContinue_Click(sender As System.Object, e
As System.EventArgs) Handles btnContinue.Click
' 1st file and mySQL Update to testing table
If txtLocation.Text.ToString <> "" And txtUnitTested.Text.ToString <> "" Then
Dim filewriter As New System.IO.StreamWriter(
"C:\Users\OER\Documents\Visual Studio 2010\Projects\frmTest1_0.txt")
Dim curItem = lstCustomer.SelectedItem
Dim now As DateTime = DateTime.Now
With filewriter
.WriteLine(vbCrLf + (now.ToString("F"))) ' Write the DateTime to the file
End With
For Each objDataRowView As DataRowView In lstCustomer.SelectedItems
Dim item As String
For Each item As DataRowView In Me.lstCustomer.Items.Item("customer")
item = String.Parse(lstCustomer.SelectedValue)
WriteLine(curItem(item))
Next item
Next ' THIS IS THE FOR LOOP I AM HAVING ISSUES WITH!!!!!!!
With filewriter
.WriteLine(vbCrLf + txtLocation.Text + vbCrLf + txtUnitTested.Text)
End With
filewriter.Close()
frmTest1.Show()
Else
MsgBox("Please Type the Location and Unit Tested!!!", vbCritical)
txtLocation.Clear()
txtUnitTested.Clear()
txtLocation.Focus()
End If

These loops:
For Each objDataRowView As DataRowView In lstCustomer.SelectedItems
Dim item As String
For Each item As DataRowView In Me.lstCustomer.Items.Item("customer")
item = String.Parse(lstCustomer.SelectedValue)
WriteLine(curItem(item))
Next item
Next
Are going to cause you some problems. You have declared a loop variable with the same name as another variable. And then you are assigning a value to it.
Also, I am not very clear on what the purpose of the two loops are. I am somewhat confused about what you are trying to accomplish in this section of code. I would start by renaming the variable in this line:
Dim item as String
I am going to use this for an example:
Dim result as string
Make that something else, and you cannot then change the value of item (since that is the loop variable) in the loop. That will cause an error.
Changing the code inside the loop to:
result = String.Parse(lstCustomer.SelectedValue)
Odds are this still won't get you to where you are trying to go, but it is a good start. Unless each item in your lstCustomer contains multiple items to iterate through I think you probably only need that first, outer loop, anyway.
If your loop starts like this:
For Each objDataRowView As DataRowView In lstCustomer.SelectedItems
Then I think you will want:
objDataRowView.Item("customer")
as what is output. I think that will be the value of the customer field from your table.
You are basically saying that this row has a column called customer.... I would like that value please.

Related

Filtering binding source

This should be easy but I am having a headbanging of a time trying to get this to work! I have done a search and tried all most EVERY SINGLE ONE. Nothing works. I have a datagrid with a binding source. A user will type text into a textbox and the grid is SUPPOSED to change to only show records that contain what user typed in the name. Simple right? NOPE! Not for me! What am I doing wrong? Code below.
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim Found As Boolean = False
Dim StringToSearch As String = ""
Dim ValueToSearchFor As String = "%" & SearchTextBox.Text.Trim.ToLower & "%"
Dim CurrentRowIndex As Integer = 0
Try
If ReferencesGrid.Rows.Count = 0 Then
CurrentRowIndex = 0
Else
CurrentRowIndex = ReferencesGrid.CurrentRow.Index + 1
End If
If CurrentRowIndex > ReferencesGrid.Rows.Count Then
CurrentRowIndex = ReferencesGrid.Rows.Count - 1
End If
If ReferencesGrid.Rows.Count > 0 Then
For Each gRow As DataGridViewRow In ReferencesGrid.Rows
StringToSearch = gRow.Cells(1).Value.ToString.Trim.ToLower
If InStr(1, StringToSearch, LCase(Trim(SearchTextBox.Text)), vbTextCompare) Then
TrainingItemBindingSource.Filter = String.Format("Name LIKE '{0}'", ValueToSearchFor)
Exit For
End If
Next
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
You should get rid of pretty much all that code. If you want to filter the data then just filter the data. There's no conditional statements required and loops required. Just set the Filter property and any records that don't match the filter will be hidden:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
TrainingItemBindingSource.Filter = $"Name LIKE '%{SearchTextBox.Text.Trim()}%'"
End Sub
As you can see, it is simple. I've no real idea what you were actually trying to achieve with the rest of that code. That will exclude any records where the Name column does not contain the search text.
Note that there is no need to try to force case-insensitivity by using ToLower or the like. Just like in real SQL, comparisons done this way in a DataTable are case-insensitive by default. You have to explicitly set the CaseSensitive property of the DataTable or its parent DataSet to True to make such comparisons case-sensitive.
I should also point out that the ability to filter is predicated on the data source implementing certain interfaces. If the data source is a DataTable then you have those interfaces for free. If you have actually bound to something else, e.g. a List(Of T), then you won't be able to filter this way because the required members do not exist.

How to solve system.invalidcastexception in vb.net

Well, i have this piece of code. I want to store the contents of a textbox into an array of strings (i prefered to do it with a list of strings) and then to print each element of the array into another textbox. However when i try to compile this code i get this error message:
System.InvalidCastException: 'Conversion from string "" to int is not valid'
FormatException: input string is not in the correct format
Any suggestions?
Public Class NewUser
Dim textUser As String
Dim strUserName As New List(Of String)
Private Sub btnCreateUser_Click(sender As Object, e As EventArgs) Handles btnCreateUser.Click
textUser = txtNewUser.Text
If textUser <> "" Then
strUserName.Add(textUser)
txtNewUser.Clear()
Else
MsgBox("Username or Password is missing. Try again!")
End If
For Each i As String In strUserName
TextBox1.Text = String.Join(",", strUserName(i))
Next i
End Sub
End Class
It's not clear to me at all what you're trying to do here:
For Each i As String In strUserName
TextBox1.Text = String.Join(",", strUserName(i))
Next i
For starters, i is a string and you're trying to use it like an integer as an index of an array. But even if you were to correct it to this:
String.Join(",", i)
That's still trying to join one string. That probably won't compile either, but even if it does it won't logically do anything. Aside from that, you're overwriting TextBox1.Text every time the loop iterates, so at best it's only ever going to equal the last value in the array.
If you're just trying to join the array into that text box, that's one line:
TextBox1.Text = String.Join(",", strUserName)
No loop required.

Adding a variable to a listBox in VB.net Windows Form

I am making a dvd database system in windows form and trying to display the dvd's entered by a user. Then display the Title, Director and Genre in 3 separate listBoxes.
When the user enters the information through 3 separate text boxes, the information is stored in a structure I made called TDvd. This means I can call for example dvd.Title or dvd.Director. I also use the variable index to add this information to an array I made called Dvd(100) (just a random number I used to test).
Here is the code I currently have for adding the items to the ListBox:
For i = 1 To noOfAddedDvds
lstTitle.Items.Add(dvd(i).Title)
lstDirector.Items.Add(dvd(i).Director)
lstGenre.Items.Add(dvd(i).Genre)
Next
The variable NoOfDvdsAdded is just a way of keeping track of the number of dvd's the user has already entered.
I run this and enter the Title, Director and Genre, but when I try and display this information across the 3 listboxes, I get the error:
An unhandled exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll
Public Class Form1
Structure TDvd
Dim Title As String
Dim Director As String
Dim Genre As String
End Structure
Dim dvd(100) As TDvd
Dim index As Integer = 0
Dim noOfAddedDvds As Integer
Private Sub btnAddToDatabase_Click(sender As Object, e As EventArgs) Handles btnAddToDatabase.Click
If txtDirector.Text <> "" Or txtGenre.Text <> "" Or txtTitle.Text <> "" Then
txtTitle.Text = dvd(index).Title
txtDirector.Text = dvd(index).Director
txtGenre.Text = dvd(index).Genre
index += 1
noOfAddedDvds += 1
End If
End Sub
Private Sub btnDisplayDatabase_Click(sender As Object, e As EventArgs) Handles btnDisplayDatabase.Click
Dim i As Integer
For i = 0 To noOfAddedDvds
MessageBox.Show(index & ", " & i)
lstTitle.Items.Add(dvd(i).Title)
lstDirector.Items.Add(dvd(i).Director)
lstGenre.Items.Add(dvd(i).Genre)
MessageBox.Show(index & ", " & i)
Next
End Sub
End Class
According to the documentation, an ArgumentNullException is thrown by the Add() method if the argument passed to it is null. (Or Nothing in VB.) So one of these is Nothing at runtime:
dvd(i).Title
dvd(i).Director
dvd(i).Genre
You'll have to debug to determine which. It would seem that the error is because you're starting your iteration at 1 instead of 0, I would think it should be:
For i = 0 To noOfAddedDvds - 1
So when you get to the index of noOfAddedDvds in your collection, that element will be an uninitialized struct with Nothing strings.
You'll definitely want to fix the iteration (indexes start at 0). Additionally, you may also benefit from initializing the String properties in your struct to String.Empty internally. Depends on whether you want similar errors to manifest as an exception or as an empty record. Sometimes the latter makes the problem more obvious since at runtime you'd see that your output started on the second record.
Just a few pointers...
The Items collection on the ListBox is actually 0 indexed, by which I mean that instead of going "1,2,3", it actually goes (0,1,2).
That's what your problem is.
Hint - think about perhaps using a List instead of an array as well... (for dvd)
Your thing cries out for being rewritten in OO form:
Friend DVDGenres
Undefined
Comedy
Action
Adventure
Sci-Fi
End Enum
Friend Class DVD
Public Property Title As String
Public Property Director As String
Public Property Genre As DVDGenres
Public Sub New
Title = ""
Director = ""
Genre = DVDGenres.Undefined
' other stuff too
End Sub
Public Overrides Function ToString As String
Return Title
End Sub
End Class
Now something to store them in. Arrays went out with Rubik's Cubes, so a List:
Private myDVDs As New List(of DVD)
A list and a class can do what arrays and structures can without the headaches. Add a DVD:
Dim d As New DVD
d.Name = TextBoxName.Text
d.Director = TextBoxDir.Text
d.Genre = comboboxGenre.SelectedItem
' add to the container:
myDVDs.Add(d)
Display all the DVDs in a ListBox to pick from:
AllDVDsLB.DataSource = myDVDs
AllDVDsLB.DisplayMember = "Title"
This will set your list as the datasource for the listbox. Whatever is in the List is automatically displayed without copying data into the Items collection. Then, say from selectedindex changed event, display the selected item details to some labels:
Label1.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Title
Label2.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Director
Label3.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Genre.ToString
Iterate to do something like what is in the Question:
For Each d As DVD in myDVDs ' CANT run out of data
lstTitle.Items.Add(d.Title)
lstDirector.Items.Add(d.Director)
lstGenre.Items.Add(d.Genre.ToString)
Next
Or iterate and reference with an Int32:
For n As Integer = 0 To myDVDs.Count - 1
lstTitle.Items.Add(myDVDs(n).Title)
' etc
Next n
HTH

loop - reading text after a certain string up until a certain string

start=AKS-RHzlSXSftLGYdBNk.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1&
For every instance of the word 'start' I need to be able to get the text after the first full stop, right up until the & symbol. E.g. 'eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1'.
There will be more than one instance of this. They will need to be appended to a listbox.
What is the simplest/quickest way to do this? (Using possibly streamreader - text file)
The simplest and quickest way will be to read each line, and check if it .StartsWith("start="). If so, then get the .IndexOf(".") and the .IndexOf("&", <whereever the first indexOf was>). Get the .SubString which encompasses those two values. I'm sure you can write the code yourself from that ;)
I tested this function with a button click, output text each line on a textbox. I am sure you can adapt this to your code.
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
txtResults.Text = ""
Dim ParseString As String
ParseString = "start=123341.23124&kjdshfkjsdaksdstart=1231.2321312&kadhskjashdkjastart=1231.23126789898&skjdfhkjsd"
Dim Delimiters() As String = New String() {"start="}
Dim Words() As String
Words = ParseString.Split(Delimiters, CompareMethod.Text)
For Each Part In Words
Dim Middle As String
Middle = Part.Split(".").Skip(1).Take(1).FirstOrDefault()
Dim Good As String
Good = Middle.Split("&").FirstOrDefault()
txtResults.Text += Good + vbNewLine
Next
End Sub
Output was
23124
2321312
23126789898
Added 31104 lines to a string and ran, took about 11 seconds to run on my laptop. Might be too slow for your app?

VB.NET Combobox - Auto-complete behaviour for numeric values

I have a problem with the auto-complete behaviour of comboboxes in VB.NET (with the .NET framework 2.0).
I am using a combobox to type in numeric values, and its DropDown list to suggest possible numeric values. This list is sorted in ascending order, for example {"10","92", "9000", "9001"}.
The combobox properties are set as follow:
AutoCompleteMode: SuggestAppend
AutoCompleteSource: ListItems
DropDownStyle: DropDown
Sorted: False
The DropDown list is simply filled like this:
myCombobox.Items.Add("10")
myCombobox.Items.Add("92")
myCombobox.Items.Add("9000")
myCombobox.Items.Add("9001")
When I don't type anything, the order of values of the DropDown list is correct, in original/ascending order. However, when I start typing something, the suggested values in the DropDown list get sorted (alphanumerically): if I type "9", the list of suggestions becomes {"9000", "9001", "92"}.
I would like to prevent this behaviour to get the values of the list in the original/ascending order. I can't figure out how...
A possible work-around would be to pad with zeroes the values in the list, e.g. {"0010", "0092", "9000", "9001"} but I would like to avoid this.
Edit:
As suggested by bendataclear, one can use a list box to display the suggestions.
This will work for small lists but doesn't scale well to large lists. It may be useful for some applications. Based on the code given by bendataclear, I made it work this way:
Private Sub ComboBox1_KeyUp(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyUp
Dim cursorPos As Integer = ComboBox1.SelectionStart
ListBox1.Items.Clear()
For Each s In ComboBox1.Items
If s.StartsWith(ComboBox1.Text) Then
ListBox1.Items.Add(s)
End If
Next
If ListBox1.Items.Count > 0 And ComboBox1.Text.Length > 0 Then
ComboBox1.Text = ListBox1.Items(0)
ComboBox1.SelectionStart = cursorPos
ComboBox1.SelectionLength = 0
End If
End Sub
The code has not been thoroughly tested and can be improved, but the main idea is there.
Edit 2:
Using DataGridView leads to better performance; it was sufficient for me. Thanks bendataclear.
Just out of curiosity, any other answer is welcomed :)
Seems to be an issue when the combo box displays the data, as even if you set a custom source it re-orders alphabetically:
ComboBox1.Items.Add("10")
ComboBox1.Items.Add("92")
ComboBox1.Items.Add("9000")
ComboBox1.Items.Add("9001")
ComboBox1.AutoCompleteCustomSource.Add("10")
ComboBox1.AutoCompleteCustomSource.Add("92")
ComboBox1.AutoCompleteCustomSource.Add("9000")
ComboBox1.AutoCompleteCustomSource.Add("9001")
ComboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
I think the only way I can think of is to create your own autocomplete something like (untested):
Dim cbotxt As String = ComboBox1.Text
Dim key As String
key = ChrW(e.KeyCode)
ListBox1.Items.Clear()
For Each i In ComboBox1.Items
Dim s As String = i.ToString()
If s.StartsWith(ComboBox1.Text & key) Then
ListBox1.Items.Add(s)
End If
Next
If ListBox1.Items.Count > 0 Then
ListBox1.Visible = True
ComboBox1.Text = ListBox1.Items(0)
End If
Edit:
A good approach for many items (I'm using for 10000+ in an application):
First change from a list box to a datagridview.
Then declare a list of strings and fill with values you want to autocomplete
Dim Numberlist as List<Of String>
' Fill List using Numberlist.Add("String")
Then in the text change property:
Filter = NumberList.FindAll(AddressOf checkNum)
DataGridView1.DataSource = Filter
And add the function to check the strings.
Function checkNum(ByVal b As String) As Boolean
If b.StartsWith(ComboBox1.Text) Then
Return True
Else
Return False
End If
End Function
This method runs on my machine with 10k items faster than I can type.