Why does this Visual Basic code work? - vb.net

What it basically does is checks if the user input is already in ComboBox1. If it is, alerts the user. If not, it adds it to the combobox
The thing I don't get is the "For Each StringIterador In ComboBox1.Items loop". How could an Item object be placed in a String variable? I know Strings are objects but... You can't just place a random object into a String variable, can you? Also the String is later used as an Item object back "ComboBox1.GetItemText(StringIterador)"
Private Sub ComboBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles ComboBox1.KeyPress
Dim StringIterador As String
If e.KeyChar = ControlChars.Cr Then
If ComboBox1.Text <> "" Then
For Each StringIterador In ComboBox1.Items
If ComboBox1.GetItemText(StringIterador).Equals(ComboBox1.Text) Then
MsgBox("ya está en la lista")
Exit Sub
Else
ComboBox1.Items.Add(ComboBox1.Text)
Exit Sub
End If
Next
End If
End If
End Sub

The documentation for the For Next statement (https://msdn.microsoft.com/en-us/library/5ebk1751.aspx) requires that "The data type of element must be such that the data type of the elements of group can be converted to it." so this code will work as long as each item can be converted to string. It's not storing the item object in a string, it's converting the item to a string and storing that.
I haven't tested this but I suspect that if you stored an object in Items that couldn't be converted to string a run-time exception would be raised. Of course since the code is adding ComboBox1.Text each time this code will only add text items and therefore won't set up a situation in which the string conversion would be invalid.
In the same way GetItemText() is documented as "If the DisplayMember property is not specified, the value returned by GetItemText is the value of the item's ToString method. Otherwise, the method returns the string value of the member specified in the DisplayMember property for the object specified in the item parameter." so, again, it's probably working because the objects added will return a string. If you added a complex object to the combobox you'd probably see the object's type displayed (which, from memory) is the fallback result of ToString().

Related

How can I read the SelectedItem of a Listbox?

I am trying to get the selected text in a ListBox to show in a list box.
I have a button that when I click, will show the text of a Selected item in a ListBox.
I've already tried getting the list box to show the text in a textbox using Listbox.SelectedItem:
Listbox1.SelectedItem = Textbox1.Text
When I do this, I get the error:
System.NullReferenceException: 'Object variable or With block variable
not set.'
Your description is somewhat upside-down.
It's not clear whether you want to set a ListBox.SelectedItem using the Text of a TextBox or you want to set a TextBox.Text with the text of the SelectedItem of a ListBox.
The code says one thing, the description another. The error you have is probably caused by a null SelectedItem (you haven't selected anything).
But, if you want to set a TextBox.Text with the ListBox.SelectedItem text, you can use the GetItemText() method. This method has a plus, it won't raise an exception if the Listbox has no selected Items (the SelectedItem is null (nothing)).
TextBox1.Text = ListBox1.GetItemText(ListBox1.SelectedItem)
The opposite:
You can use the ListBox FindString() and FindStringExact() methods to locate an item in the control's collection corresponding to a given string.
The former finds the first items in the ListBox that starts with the specified string, the latter matches only the whole string.
The search can begin from a specific index. It's not case sensitive.
listBox1.SelectedIndex = listBox1.FindString(textBox1.Text, 0)
' or
listBox1.SelectedIndex = listBox1.FindStringExact(textBox1.Text, 0)
You can continue the search specifying, as the starting point, the index of the item previously found:
private int lboxSearchIndex = -1;
Private Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
lboxSearchIndex = listBox1.FindString(textBox1.Text, lboxSearchIndex)
listBox1.SelectedIndex = lboxSearchIndex
End Sub
Setting the SelectedItem is like using the FindStringExact() method.
Only a full match will set the item, but it's case sensitive.
Listbox1.Text=textbox1.text
Let me know its help you

How do I select specific variables based on checkbox state as I iterate through a For Each

I'm working on a project that requires I iterate through a list of controls on a tabpage to find all of the checkboxes. Then depending on the state of the box (checked or unchecked) select individual variables (filenames) to then perform either a batch rename or delete of files on the filesystem (cb.checked = perform action).
I have managed to create the "for each" for the iteration of the controls (thanks google) but I'm struggling to figure out how to pick the variables. They are all named differently, obviously, as are the checkboxes. Also the checkboxes are statically assigned to the form/tabpage. Here's what I have at the moment.
Public Sub delBut_code(ByRef fname As String)
If (Sanity = 1) Then
For Each cb As Control In Form1.Controls
If TypeOf cb Is CheckBox AndAlso DirectCast(cb,
CheckBox).Checked Then
If My.Computer.FileSystem.FileExists(fname) Then
My.Computer.FileSystem.DeleteFile(fname)
End If
End If
Next
MessageBox.Show("All Actions Completed Successfully")
Else
MessageBox.Show("Please select a File To Delete")
End If
End Sub
and here is an example of some of the variables:
Dim castle As String = selPath & "\zm_castle_loadingmovie.txt"
Dim factory As String = selPath &
"\zm_factory_load_factoryloadingmovie.txt"
Dim island As String = selPath & "\zm_island_loadingmovie.txt"
N.B selpath collects a user entered folder path and can be ignored here
I would really appreciate any pointers.
First, you can do much better with the loop:
Public Sub delBut_code(ByRef fname As String)
If Sanity <> 1 Then
MessageBox.Show("Please select a File To Delete")
Exit Sub
End If
Dim checked = Form1.Controls.OfType(Of CheckBox)().Where(Function(c) c.Checked)
For Each box As CheckBox in checked
Try
'A file not existing is only one reason among many this could fail,
' so it needs to be in a Try/Catch block.
' And once you're using a Try/Catch block anyway,
' the FileExists() check becomes a slow and unnecessary extra trip to the disk.
My.Computer.FileSystem.DeleteFile(fname)
Catch
'Do something here to let the user know it failed for this file
End Try
Next
MessageBox.Show("All Actions Completed")
End Sub
But now you need to know how have the right value in that fname variable. There's not enough information in the question for us to fully answer this, but we can give some suggestions. There a number of ways you could do this:
Set the Tag property in the Checkboxes when you build the string variables. Then fname becomes DirectCast(box.Tag, String).
Inherit a custom control from CheckBox to use instead of a normal Checkbox that has an additional String property for the file name. Set this property when you build the string variables.
Name your string variables in a way that you can derive the string variable name from the CheckBox variable name, and then use a Switch to pick the right string variable from each box.Name.
Keep a Dictionary(Of CheckBox, String) that maps the Checkboxes to the right string values.
But without knowing more context of the application, I hesitate to recommend any of these over the others as best for your situation.

Reading Numbers from Webbrowser Vb.net

In my WebBrowser I got text like this: Remaining balance: 10$
I would like to convert it to another currency, I want just to read number from my browser, then after that I will send it to a Label or TextBox with the new converted currency. I am stuck here.
A screenshot of it
Private Sub LinkLabel2_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel2.LinkClicked
WebBrowser2.Navigate(TextBox9.Text + TextBox2.Text)
End Sub
Private Sub WebBrowser2_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser2.DocumentCompleted
Label1.Text = (WebBrowser2.Document.Body.InnerText)
End Sub
I have this suggestion (I know this is probably not the perfect solution):
First, try loading that same webpage in a normal web browser such as Google Chrome or Firefox or any browser which has the feature to "inspect elements", meaning to view their HTML code.
Find out the element which displays the price you want.
Note down the ID of the element (usually written something like id="someID")
Back to your program's code, include the following Function, which will get the text displayed and convert it to another currency:
Public Function ConvertDisplayedCurrency() As Decimal
Dim MyCurrencyElement As HtmlElement = WebBrowser2.Document.GetElementById("theIdYouGotInStep3") 'This will refer to the element you want.
Dim TheTextDisplayed As String = MyCurrencyElement.InnerText 'This will refer to the text that is displayed.
'Assuming that the text begins like "Remaining balance: ###", you need to strip off that first part, which is "Remaining balance: ".
Dim TheNumberDisplayed As String = TheTextDisplayed.Substring(19)
'The final variable TheNumberDisplayed will be resulting into a String like only the number.
Dim ParsedNumber As Decimal = 0 'A variable which will be used below.
Dim ParseSucceeded As Boolean = Decimal.TryParse(TheNumberDisplayed, ParsedNumber)
'The statement above will TRY converting the String TheNumberDisplayed to a Decimal.
'If it succeeds, the number will be set to the variable ParsedNumber and the variable
'ParseSucceeded will be True. If the conversion fails, the ParseSucceeded will be set
'to False.
If Not ParseSucceeded = True Then Return 0 : Exit Function 'This will return 0 and quit the Function if the parse was a failure.
'Now here comes your turn. Write your own statements to convert the number "ParsedNumber"
'to your new currency and finally write "Return MyFinalVariableName" in the end.
End Function
Call that Function probably when the document of the WebBrowser2 loads, that is, in the WebBrowser2_DocumentCompleted sub.
I hope it helps!

Passing names of class fields to a private sub to update in VB.Net

I thought this might be simple to achieve, but I can't figure out how to make it work.
I have a series of fields within a class that I want to check the value of. So instead of writing the same if ... then ... else statement I thought passing this through a private method would be ideal.
Private Sub checkParameter(ByRef p_param As Object, ByRef p_private_field As Object, p_exception As String)
If Not p_param Then
Throw New Exception(p_exception)
Else
p_private_field = p_param
End If
End Sub
Of course the problem is that I want the p_private_field to be the actual private field I am passing in.
So if I called the method with the following code:
checkParameter(i_input_folder, "p_input_folder", "Input folder must be supplied")
Then the method would check that i_input_folder did have a value and if so then assign it to the private field p_input_folder and if not throw the exception with the message provided.
Any help would be greatly appreciated.
Cheers
Seems just like a little typo
checkParameter(i_input_folder, "p_input_folder", "Input folder must be supplied")
You pass in your second parameter as string (the name of the filed i guess), but you have to pass the object itself
checkParameter(i_input_folder, p_input_folder, "Input folder must be supplied")

Vb.net how can I set Search level as user input string

Intro... I've got a counter in my project that counts files in specified paths. Now all this depends on the users input as concerned would go into settings and set which extensions (tbExt1.text) that should be searched for as well as path (tbpath.text). The paths are listed in lbchannel1 listbox. Now this wont matter too much to my question, but I filled it in so my example below is more understandable.
Here comes the question: The users should be able to address if its going to count TopLevelOnly (FileIO.SearchOption.SearchTopLevelOnly) or TopAndSub (FileIO.SearchOption.SearchAllSubDirectories).
So I made a combobox that they can select from either of those two options. When they select one of them, FileIO.SearchOption.SearchTopLevelOnly or FileIO.SearchOption.SearchAllSubDirectories will become the text in a textbox tbTopOrSub1.text
That brings me to the next part. Instead of for example FileIO.SearchOption.SearchAllSubDirectories in my counter, I now added tbTopOrSub1.text as I hoped this would work the same way, but now be a user depended option. Have a look:
Dim TopOrSub1 As String
TopOrSub1 = tbTopOrSub1.Text
Dim fileTotal As Integer
For Each item As String In lbChannel1.Items
fileTotal += My.Computer.FileSystem.GetFiles(item.ToString, TopOrSub1, (tbExt1.Text)).Count
Next
I thought this would work like a charm, but it doesn't seem to work. I get this error The converting from string FileIO.SearchOption.SearchTopLev to type Integer is not valid (could be bad translation since the error was in Norwegian) and I notice how it sais TopLev. I suppose its too long? I can't figure out how to get around this.
First of all put Option Strict On for your VB project. This helps alot to avoid runtime errors.
The error occurs since you try to convert a string into an enumeration (=integer).
The good thing about comboboxes is that they have a DataSource property which can hold a collection of objects of any type. Additionally they have the following Properties:
DisplayMember: Name of a (public) property of the object set
in DataSource. The value of it will be displayed in the UI as "friendly" text.
ValueMember: Name of a property of the object set in DataSource. This value will not be shown in UI but you can accesss it in your code.
See my below exmaple how to use all these:
The object which holds the display text (Name) and the Value for your File Search Option:
Class FileSearchOption
Public Property Name As String
Public Property Value As FileIO.SearchOption
End Class
Fill your combobox and set its DataSource, DisplayMember and ValueMember:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim searchOptions As New List(Of FileSearchOption)
searchOptions.Add(New FileSearchOption() With {.Name = "TopLevelOnly", .Value = FileIO.SearchOption.SearchTopLevelOnly})
searchOptions.Add(New FileSearchOption() With {.Name = "TopAndSub", .Value = FileIO.SearchOption.SearchAllSubDirectories})
ComboBox1.DataSource = searchOptions
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "Value"
End Sub
Handle the action when the user has chosen a search option. Remark that it is necessary to DirectCast the SelectedValue since it is of type Object.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim fileTotal As Integer
For Each item As String In {"G:\"}
fileTotal += My.Computer.FileSystem.GetFiles(item.ToString, DirectCast(ComboBox1.SelectedValue, FileIO.SearchOption), (tbExt1.Text)).Count
Next
End Sub