Checkedlistbox: uncheck items and re-run action upon new selection - vb.net

I have a checkedlistbox1 which is filled through a search function with a folderbrowserdialog. Once I check one item (=XML file) it fills a listbox according to certain nodes by calling a separate class. This works fine.
What I want it to do next is when I select another item in checkedlistbox1 it unchecks the previously checked item and again runs the separate class to display the nodes of the newly selected item.
My code is a blur of tries according to other searches I've made. Please take note of what I want it to do, this is not like I have my code now because I don't want it to throw an error when I select another item. I just want it to de-select the previous and perform the action again on the newly selected item.
I hope someone can help me out on this one.
code:
Try
Dim checkLstBox As CheckedListBox = CType(sender, CheckedListBox)
Dim targetNum As Integer = 1
If e.NewValue = CheckState.Checked AndAlso checkLstBox.CheckedItems.Count + 1 > targetNum Then
Call ClsMessageBoxes.CheckedListbox1_maxcheck_Form2()
e.NewValue = CheckState.Unchecked
For i As Integer = 0 To f5.CheckedListBox1.Items.Count - 1
f5.CheckedListBox1.SetItemChecked(i, False)
Next 'This part at least throws an error if I select a new item in checkedlistbox1 and de-selects the previous item'
Else
'this part does not work'
f5.ListBoxDestPlate.Items.Clear()
f5.CheckedListlistbox2.SelectedItems.Clear()
'this part is meant to select an item in another checkbox according to certain tekst in the filename'
Dim i As Integer
If ClsSharedProperties2.filePath2.Contains("Text1") Then
i = 1
f5.Checkedlistbox2.SetItemChecked(i, True)
Call ClsScan.scanning2()
ElseIf ClsSharedProperties2.filePath2.Contains("Text2") Then
i = 2
f5.Checkedlistbox2.SetItemChecked(i, True)
Call ClsScan.scanning2()
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message & vbCrLf & "Stack Trace: " & vbCrLf & ex.StackTrace)
End Try

Your code is a bit messy with references to other forms I'm guessing (f5? ClsScan?).
In general, this code will work with the checked item and uncheck any existing items:
Private Sub clb_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles clb.ItemCheck
If e.NewValue = CheckState.Checked Then
For Each i As Integer In clb.CheckedIndices
clb.SetItemChecked(i, False)
Next
MessageBox.Show("Checked " & clb.Items(e.Index).ToString)
End If
End Sub
The MessageBox line would be replaced with you passing the item reference to whatever function or method you need to do your filtering.
One thing to note regarding the ItemCheck event is that the item in the collection isn't actually checked yet. That is why you would have to rely on the e.Index value.

Related

How to remove a Specific Button from Flow Layout Panel

I am creating dynamic buttons, each has a unique Tag, each tag is then sent to a list box. i want to be able to select the tag from the list box and click a button to remove the button with that specific tag i tried making this code but no go....
Private Sub cmdRemove_Click(sender As Object, e As EventArgs) Handles cmdRemove.Click
Try
Dim curItem As String = RmvList.SelectedItem.ToString()
MsgBox(curItem)
For Each Button As System.Windows.Forms.Control In Main.FloLay.Controls
If Button.Tag = curItem Then
Main.FloLay.Controls.RemoveAt(CurItem)
End If
Next
Catch ex1 As Exception
End Try
End Sub
How can i Achieve this Feat? Thank you In Advance.
RemoveAt takes a number as parameter that is the index in the collection.
You have to do two things:
Use Remove instead of RemoveAt
Exit the for loop
So the code:
For Each Button As System.Windows.Forms.Control In Main.FloLay.Controls
If Button.Tag = curItem Then
Main.FloLay.Controls.Remove(Button)
Exit For
End If
Next
The first change is obvious, the second change is needed because you alter the enumerator when you remove the button and it would throw an exception if you try to continue the for loop after the deletion.
If you want to delete multiple items you can use the following trick:
For i = Main.FloLay.Controls.Count -1 To 0 Step -1
If Main.FloLay.Controls(i).Tag = curItem Then
Main.FloLay.Controls.RemoveAt(i) 'Here you actually provide the index!
End If
Next
This will work because you don't alter any index yet to come be deleting an item if you move backwards through the collection.

VB.NET - Combobox goes blank when a button is clicked, databind doesn't update

Please forgive me, it has been some time since I've used VB.Net so this may be easy.
I have a simple login form with a text box, combobox and a button. The combobox is binded to a SQL database and displays the user names from Users table. The idea is that you select a name, type in a password, and you logon to a new form (This part works Great!). If you type a wrong password, the form pops up a message that says "invalid." For some reason at this stage, the combobox goes blank. The drop down now has empty spaces where names once were. Typing in a name with a password here results in object reference errors. I have tried everything to get the combo box to reset and searched the web but nothing works!!!
(I know this is not a secure login, this is just an easy example of binding data to a combo box and checking it against SQL table). Thanks for your help!
enter code here
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles BTN_Logon.Click
Try
Dim STR_User As String = Users_nameComboBox.SelectedValue
Dim STR_Pwd As String = TB_Pwd.Text
STR_User = STR_User.Trim
'MessageBox.Show(STR_User & "|" & STR_Pwd)'Used to verify this stage works
Dim numRecords As Int16 = UsersTableAdapter.FillByLogin(Me.Login_testDataSet.users, STR_User, STR_Pwd)
'MessageBox.Show(numRecords) 'Used to verify this stage works
If (numRecords > 0) Then
Dim DB_User As String = Me.Login_testDataSet.users(0).users_name.Trim
Dim DB_Pwd As String = Me.Login_testDataSet.users(0).users_pwd.Trim
'MessageBox.Show(DB_User & "|" & DB_Pwd)'Used to verify this stage works
If DB_User.Equals(STR_User) And DB_Pwd.Equals(STR_Pwd) Then
'User is authenticated for application
'This section works (removed to cleanup code)
Else
MessageBox.Show("ERROR" & STR_User & "|" & STR_Pwd) 'Shows that this stage works
'Need to figure out why combobox doesn't refill, using restart for now
'Application.Restart()
End If
End If
MessageBox.Show("ERROR" & STR_User & "|" & STR_Pwd) 'Shows that this stage works
'Need to figure out why combobox doesn't refill, using restart for now
'Application.Restart()
Catch ex As Exception
MessageBox.Show(ex.Message)
'Need to figure out why combobox doesn't refill, using restart for now
'Application.Restart()
End Try
End Sub
InitializeComponent
'Users_nameComboBox
Me.Users_nameComboBox.DataBindings.Add(New System.Windows.Forms.Binding("Text",
Me.UsersBindingSource, "users_name", True))
Me.Users_nameComboBox.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", Me.UsersBindingSource, "users_name", True))
Me.Users_nameComboBox.DataSource = Me.UsersBindingSource
Me.Users_nameComboBox.DisplayMember = "users_name"
Me.Users_nameComboBox.Name = "Users_nameComboBox"
Me.Users_nameComboBox.ValueMember = "users_name"

Accessing controls located in a dynamically created user control vb.net

I am a casual programmer with not a lot of experience. I am happy I have made it this far on my own (with help of course from this site and others like it). But now I need some help.
I have created a user control with several text boxes, masked text boxes, combo boxes, a check box and 3 buttons.
I have created a form (Form1) with a tab control (TabControl1) that has 1 tab page on it (TabPage1). I have added my user control to TabPage1 and the control assumes the name ContactTab1. This was done through the VB.net form design, not by code.
When I run my form I have code so that when I click on my add button, it adds another tab with my user control added to it (no matter which tab I may be on). It works great, I can add as many tabs as I want. When I click on my edit or delete button, they work great in the sense that I know which tab the button is on when it gets clicked. My problem is when I click the edit button I need to set ckbDeleteContact.Checked = False and ckbDeleteContact.Visible = False on the tab that the button was clicked. When I click the delete button I need to set ckbDeleteContact.Checked = True and ckbDeleteContact.Visible = True on the tab that the button was clicked. I can access the check box on the first tab without a problem with the statement ContactTab1.ckbDeleteContact.Checked = False.
So my question is, how do I access all these text boxes, masked text boxes, combo boxes, and my check box on these dynamically added controls? Below is my code for Form1 and I have commented out what I need working:
Public Class Form1
Private intTabPage As Integer = 1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TabPage1.Text = "Contact #" & intTabPage
ContactTab1.ckbDeleteContact.Checked = False
ContactTab1.ckbDeleteContact.Visible = False
TabPage1.Name = "TabPage" & intTabPage
intTabPage = intTabPage + 1
End Sub
Private Sub UC_btnAddContact_Click() Handles ContactTab1.UC_btnAddContact_Click
AddNewTab()
End Sub
Private Sub UC_btnEditContact_Click() Handles ContactTab1.UC_btnEditContact_Click
'**DEBUG: See which tab the button is on when clicked
MessageBox.Show("The edit button from the following tab was clicked: " & TabControl1.SelectedTab.Name() & vbCrLf & "The edit button on the following contact tab was clicked: " & TabControl1.SelectedTab.Controls.Item(0).Name(), "Check", MessageBoxButtons.OK, MessageBoxIcon.Information)
'This code is what needs to work. ContactTabObject would have naming convention "ContactTabX" where X = the tab # 1 through the highest tab #
'ContactTabObject.ckbDeleteContact.Checked = False
'ContactTabObject.ckbDeleteContact.Visible = False
End Sub
Private Sub UC_btnDeleteContact_Click() Handles ContactTab1.UC_btnDeleteContact_Click
'**DEBUG: See which tab the button is on when clicked
MessageBox.Show("The delete button from the following tab was clicked: " & TabControl1.SelectedTab.Name() & vbCrLf & "The delete button on the following contact tab was clicked: " & TabControl1.SelectedTab.Controls.Item(0).Name(), "Check", MessageBoxButtons.OK, MessageBoxIcon.Information)
'This code is what needs to work. ContactTabObject would have naming convention "ContactTabX" where X = the tab # 1 through the highest tab #
'ContactTabObject.ckbDeleteContact.Visible = True
'ContactTabObject.ckbDeleteContact.Checked = True
End Sub
Function AddNewTab()
Dim NewTab As New TabPage
Dim NewContactTab As New ContactTab
TabControl1.Controls.Add(NewTab)
TabControl1.SelectTab(NewTab)
NewTab.Text = "Contact #" & intTabPage
NewTab.BackColor = System.Drawing.Color.Transparent
NewTab.Controls.Add(NewContactTab)
NewTab.Name = "TabPage" & intTabPage
NewContactTab.Location = New System.Drawing.Point(6, 6)
NewContactTab.BackColor = System.Drawing.Color.Transparent
NewContactTab.ckbDeleteContact.Checked = False
NewContactTab.ckbDeleteContact.Visible = False
AddHandler (NewContactTab.btnAddContact.Click), AddressOf UC_btnAddContact_Click
AddHandler (NewContactTab.btnEditContact.Click), AddressOf UC_btnEditContact_Click
AddHandler (NewContactTab.btnDeleteContact.Click), AddressOf UC_btnDeleteContact_Click
NewContactTab.Name = "ContactTab" & intTabPage
intTabPage = intTabPage + 1
End Function
End Class
Once I get this figured out, I should be good to go and I should be able to get the rest on my own. In case you are wondering, I will also be filling in the options for my combo boxes with data from a database. I will then be using the form to take all the data in it and either adding, editing, or deleting the information from a database.
Thanks in advance.
As #HansPassant said you just need to add properties to your user control to get access to your controls in it. I'm not a vb.net guy, but I think this is going to help you:
Public Function MyTextbox() As System.Windows.Forms.TextBox
Return Textbox1
End Function
You can write this in your user control code.
Ok, maybe I was not the clearest in my post or I just don't understand the encapsulation thing. I can access all my controls since they are standard controls. I just needed to know how I could get the name of the parent control, which in this case is the user defined control named ContactTabX where X = 1 through n controls that were added when I pressed my add button n times. I could always access them by saying something likeContactTab5.ckbDeleteContact.Visible = True or whatever. I did not want to hardcode since I would not be sure how many tabs were added so I wanted a way to know which tab I was on when the button was pressed that way I could change that check box property on that particular tab (since every tab is identical).
I spent hours trying to figure it out and well here is what I was able to figure out about 10 mins after posting the question (go figure). I hope this helps anyone else. And for you experts out there, any feedback is appreciated on my solution. I always like to learn :)
So replacing the subs I originally posted with these worked perfectly.
Private Sub UC_btnEditContact_Click() Handles ContactTab1.UC_btnEditContact_Click
'**DEBUG: See which tab the button is on when clicked
'MessageBox.Show("The edit button from the following tab was clicked: " & TabControl1.SelectedTab.Name() & vbCrLf & "The edit button on the following contact tab was clicked: " & TabControl1.SelectedTab.Controls.Item(0).Name(), "Check", MessageBoxButtons.OK, MessageBoxIcon.Information)
Dim Contact As ContactTab = TabControl1.SelectedTab.Controls.Item(0)
Contact.Name = TabControl1.SelectedTab.Controls.Item(0).Name()
Contact.ckbDeleteContact.Visible = False
Contact.ckbDeleteContact.Checked = False
Contact = Nothing
End Sub
Private Sub UC_btnDeleteContact_Click() Handles ContactTab1.UC_btnDeleteContact_Click
'**DEBUG: See which tab the button is on when clicked
' MessageBox.Show("The delete button from the following tab was clicked: " & TabControl1.SelectedTab.Name() & vbCrLf & "The delete button on the following contact tab was clicked: " & TabControl1.SelectedTab.Controls.Item(0).Name(), "Check", MessageBoxButtons.OK, MessageBoxIcon.Information)
Dim Contact As ContactTab = TabControl1.SelectedTab.Controls.Item(0)
Contact.Name = TabControl1.SelectedTab.Controls.Item(0).Name()
Contact.ckbDeleteContact.Visible = True
Contact.ckbDeleteContact.Checked = True
Contact = Nothing
End Sub
Thanks again for the input.

How to change the data source of a ComboBox?

I have two comboboxes. The data sorce of combobox1 is a list of string that is fixed. Combobox2's data sorce will be a list of string that depends on the selection of combobox1. This is very similar to a common case as follows: first enter your contry, then depending on your enter, the second combobox will show you the list of universities in the country.
'Change selection of first combobox
Private Sub cbxClient_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbxClient.SelectedIndexChanged
Try
If cbxClient.SelectedIndex <> -1 Then
GetAccount()
End If
Catch
Throw
End Try
End Sub
'Based on selection of first combobox, update the data sorce of second combobox
Private Sub GetAccount()
Try
m_listAccount.Clear()
Dim strClient As String = cbxClient.SelectedItem.ToString
For i As Integer = 0 To m_listDS.Count - 1
If m_listDS(i).Client.Tostring = strClient Then
m_ds = m_listDS(i)
Exit For
End If
Next
If Not m_ds Is Nothing Then
For Each row As DataRow In m_ds.Tables("Account").Rows
m_listAccount.Add(row("account").ToString)
Next
End If
cbxAccount.DataSource = m_listAccount
Catch ex As Exception
End Try
End Sub
My problem is that though m_listAccount updates (has the correct information), the choices shown in cbxAccount are not updated according to m_listAccount (has the wrong information). I do not understand why this happens.
Note: Assume that old string in m_listAccount is {"old1"} (the list only has 1 string) and after updating, the string in m_listAccount is {"new"}. Through break points, I get the following:
cbxAccount.DataSorce={"new"}
cbxAccount.SelectedItem={"old1"}
In the form, cbxAccount shows "old1" string.
Try this,
cbxAccount.DataSource = Nothing
cbxAccount.DataSource = m_listAccount
If you are just updating the same list object, the datasource might not automatically update, but should if the pointer changes to the datasource.
Or you could try,
m_listAccount.AcceptChanges()
If m_listAccount is a DataTable
Doesn't look like you're actually calling the databind method, i.e.
cbxAccount.DataBind()
Try putting that just after you set the data source.

How to wait for a Visual Basic 2010 form's button-click event to end

In my vb program, I have two forms that work together to allow you to define an almost arbitrary amount of designs. In the first form, there is a two-dimensional array, storing an integer (not important) and an ID class that I defined as a public inner class in another form. Clicking on the "Define ID" button in this form will take you to the next form, where you will define a new ID or edit an old one based off of an index in the array you selected or entered in the first form's combo box, using multiple fields in the second form to define its different aspects. What I want to happen is the first form's code to be suspended as the user defines the ID in the second form, then they click on the Continue button on the second form. After a bit of error-checking, the form either is momentarily hidden (which is how I originally implemented it) or returns the edited ID object, but only if the error-checking does not indicate any input is incorrect. Originally, I simply grabbed the ID by using newForm.curID and set that to its spot in the array, waiting for the user to finish by using newForm.showDialog(), but sometimes the program would return a null exception because I don't think I copy the IDs correctly. Also, though the errors show up for a small amount of time, the Continue button saves the ID regardless of its correctness. Is there a way to manipulate the showDialog to get a result response out of it?
Short version: I need to either return an object of an inner class in one form to an array in a calling form or wait for a form to finish and use the calling form to copy its object, then close the callee form.
First Form's "Define" button method
Private Sub DesignButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DesignButton.Click
Me.totalCoilBox.Focus() 'calls validating method, makes textbox yellow if invalid'
If totalCoilBox.BackColor = Color.White Then
Dim newForm As New IVD_DesignData 'creates an object of ID called curID as well'
Try
If DesignIDBox.Items.Contains(DesignIDBox.Text) Then 'design exists
set the curID to the one already in the array'
newForm.curID = CGID(Integer.Parse(DesignIDBox.Text), 1)
'set number of coils to new number, if applicable'
CGID(Integer.Parse(DesignIDBox.Text), 0) = Integer.Parse(DesignIDBox.Text)
'show dialog for editing'
newForm.ShowDialog()
'put the (edited) curID back into the array'
CGID(Integer.Parse(DesignIDBox.Text), 1) = newForm.curID
Else 'design does not exist, make a new one
put number of coils into new array spot'
CGID(Integer.Parse(DesignIDBox.Text), 0) = Integer.Parse(totalCoilBox.Text)
'set the design ID to the number of defined IDs plus one'
newForm.curID.designID = Integer.Parse(DesignIDBox.Text)
'show dialog for editing'
newForm.ShowDialog()
'add curID into the array'
CGID(Integer.Parse(DesignIDBox.Text), 1) = newForm.curID
'add that design number to the dropdown box'
DesignIDBox.Items.Add(newForm.curID.ToString())
'increment number of defined designs'
Current_IDBox.Text = Integer.Parse(Current_IDBox.Text) + 1
End If
Catch ex As ArgumentOutOfRangeException 'dropdown box has no elements in it;
do the same as adding a new ID:
put number of coils into new array spot'
CGID(Integer.Parse(DesignIDBox.Text), 0) = Integer.Parse(totalCoilBox.Text)
'set the design ID to the number of defined IDs plus one'
newForm.curID.designID = Integer.Parse(DesignIDBox.Text)
'show dialog for editing'
newForm.showDialog()
'add curID into the array'
CGID(Integer.Parse(DesignIDBox.Text), 1) = newForm.curID
'add that design number to the dropdown box'
DesignIDBox.Items.Add(newForm.curID.ToString())
'increment number of defined designs'
Current_IDBox.Text = Integer.Parse(Current_IDBox.Text) + 1
End Try
DesignIDBox.Text = newForm.curID.ToString()
newForm.Close()
End If
Second Form's "Continue" button method
Private Sub ContinueButton_Click(ByVal sender As System.Object, ByVal e As ByVal e As System.EventArgs) Handles ContinueButton.Click
Me.NTBox.Focus()
Me.IDBox.Focus()
Me.ODBox.Focus()
Me.TBox.Focus()
Me.WBox.Focus()
If HSCBox.Checked Then
Me.HSC_MultBox.Focus()
Else
curID.HSC = "n"
curID.HSC_Mult = 1
End If
If NTBox.BackColor = Color.White And IDBox.BackColor = Color.White And ODBox.BackColor = Color.White And TBox.BackColor = Color.White And WBox.BackColor = Color.White And ((HSCBox.Checked And HSC_MultBox.BackColor = Color.White) Or Not (HSCBox.Checked)) Then
'success! window falls back?'
End If
End Sub
Thanks for any and all help! I'm much more proficient in Java, so this VB project is a bit frustrating sometimes.
On your second form, make a method like this:
public function ReturnSomething(curId as whateverType) as whateverReturnType
me.curId = curId
me.showDialog
return someValue
end function
then call that from your first form.
EDIT: also, have your second form's Continue method call Me.Close. This will close the second form. The ShowDialog call will block until the form is closed.
The first form should not be calling the second form's close method.