Check which checkbox is checked with loop - vb.net

What would be the syntax to check inside a visual basic form panel for checkboxes and find which are checked? I understand how I Could use a for loop and an if statement, but I'm confused as to the syntax to check for each checkbox. for example:
Dim i As Integer
For i = 1 To 10
'Here is where my code would go.
'I could have ten checkboxes named in sequence (cb1, cb2, etc),
'but how could I put i inside the name to test each checkbox?
Next

You need to loop through the Controls collection of the control that has the Checkbox's added to it. Each Control object has a Controls collection. I would prefer a For Each loop in this scenario so I get the Control right away without having to get it using the Controls index If your CheckBoxes are added to the Panel directly, the easiest way to do it would be..
For Each ctrl As var In panel.Controls
If TypeOf ctrl Is CheckBox AndAlso DirectCast(ctrl, CheckBox).IsChecked Then
'Do Something
End If
Next

I'm not very familiar with the VB.Net syntax, but in psudo-code:
ForEach CheckBox in ControlContainer
DoSomething
Next
If you have all of your CheckBox controls in a single container - e.g. a Panel - then the above code would iterate each control that is a CheckBox.

Try this :
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If CheckBoxList1.Text = "" Then
do/display something
Exit Sub
Else
For Each item As ListItem In CheckBoxList1.Items
If item.Selected Then
do/display something
End If
Next
End If
End Sub

Related

How to exclude some controls in a FOR EACH CONTROL Loop?

So I have a neat little function that I use to make sure only one checkbox can be checked inside a GroupBox.
This is what it looks like...
Private Sub ToggleCheckBoxOnEntry(sender As Object, e As EventArgs)
'This handles mutually exclusivity for the check boxes so that only one is ever allowed to be checked
Static CurrentlySelectedbox As CheckBox
If CType(sender, CheckBox).Checked Then
CurrentlySelectedbox = sender
End If
For Each cntrl As CheckBox In gbxReports.Controls
If cntrl.Checked AndAlso cntrl.Name <> CurrentlySelectedbox.Name Then
cntrl.Checked = False
End If
Next
End Sub
And for each checkBox_CheckChanged I include this line...
Private Sub chkReports_CheckedChanged(sender As Object, e As EventArgs)
ToggleCheckBoxOnEntry(sender, e)
End Sub
So I have this great looking groupbox with about 10 reports and it works great. The problem comes when I try to include a combobox for one of the extracts where I let the user select something from a drop down and use it as a parameter. I do not want to include it outside of the GroupBox (unless there's no way to fix my issue), however, if I include it inside of it I get an error..
Unable to cast object of type 'System.Windows.Forms.ComboBox' to type
'System.Windows.Forms.CheckBox'.
Is there a way for me to exclude some controls from the loop such as
For each cntrl as CheckBox in gbxReports.controls // except comboboxes/ or only checkboxes??
The only controls that I would potentially have in the group box are checkboxes and comboboxes.
Why don't you be specific to what you want to loop rather than the mix of Controls:
For Each chexkb As Checkbox In Controls.OfType(Of Checkbox)()
'do the loop just on the check boxes
Next

Get the names of the datagridview present in the form

How can I check the number of DataGridViews on a form, and then display present their names in VB.NET?
I have tried this:
For Each dgv As DataGridView In Me.Controls
MsgBox(dgv.Name)
Next
But my guess is that Me.Controls consists of every other form controls except DataGridView?
For Each _control In Me.Controls
If TypeOf _control Is DataGridView Then
MsgBox(_control.Name)
End If
Next
I know this question is posted long time ago. In answer posted by #AadityaDengle You'll get DataGridView controls placed in form but, if DataGridView is nested in some other control (for example Panel, TableLayoutPanel, GroupBox, ...) it will not find it.
You have to search in all controls using "recursive search" way. Below is example :
'there will be stored names(id) of all DataGridView controls
Private allGrids As String = ""
Private Sub getAllGrids()
'loop through all controls on a form
For Each c As Control In Me.Controls
If TypeOf c Is DataGridView Then
'if control is DataGridView, then collect her name(id)
allGrids += c.Name.ToString + ","
Else
'if control isn't type of DataGridView and have child control(s), loop through that control
'(for example Panel, TableLayoutPanel,GroupBox, ...)
If c.HasChildren = True Then getAllGrids(c)
End If
Next
End Sub
Private Sub getAllGrids(cnt As Control)
'loop through all controls on a "container" control
'the search principle is the same like in getAllGrids on a form
For Each c As Control In cnt.Controls
If TypeOf c Is DataGridView Then
'collect DataGridView name(id)
allGrids += c.Name.ToString + ","
Else
'subroutine call hisself again with new control
If c.HasChildren = True Then getAllGrids(c)
End If
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox(allGrids)
End Sub
Even though both answers by #AadityaDengle and #nelek are right I will leave my code here that I think it's a little more structured.
Note that this code does work with or without your DataGridView is placed inside a Panel or a GroupBox.
'Loop throught all DataGridViews in your Form
Private Sub FormDGV(ByVal Controlo As Control)
If Controlo.HasChildren Then
If TypeOf Controlo Is DataGridView Then
MessageBox.Show(Controlo.Name)
End If
For Each Control As Control In Controlo.Controls
FormDGV(Control)
Next
End If
End SubĀ“
If your DataGridViews are nested in a Panel or something like that you need to send the specifc Panel through parameter like this -
FormDGV(YourPanel)
But if they are not, you just need to send the form itselt.

Visual Basic - Performing an action on an object that has the focus

I'm trying to do something very simple:
Create a method that handles multiple textbox.gotFocus() events in my form.
The goal is to select all text when the focus is given to any of the textboxes.
I know I could create an if-else block that checks to see whether or not each textbox has the focus, and then if so, just do textbox1.selectall(), or textbox2.selectall(), etc.
Is there a quicker way to do this that I'm missing that would just do it all in one statement that uses something like object.focused.selectall()? I know these aren't keywords in vb, but they're the best descriptive words I can think of to explain what I'm trying to do.
Any input is appreciated. Thanks!
What you want to do is more complicated than you think. You would have to create an event to trigger the method that handles the textboxes focus. The easy way is to put as you said a selectAll() method in every textbox gotFocus event.
Nothing built in to do that, unless you inherit from the TextBox and call SelectAll in the OnEnter override method yourself.
If you have a lot of TextBox controls, you could just iterate over the collections and add the method yourself:
Public Sub New()
InitializeComponent()
Dim ctrls As New Stack(Of Control)
ctrls.Push(Me)
While ctrls.Count > 0
Dim ctrl As Control = ctrls.Pop
If ctrl.Controls.Count > 0 Then
For Each c As Control In ctrl.Controls
ctrls.Push(c)
Next
Else
If TypeOf ctrl Is TextBox Then
AddHandler ctrl.Enter, Sub() DirectCast(ctrl, TextBox).SelectAll()
End If
End If
End While
End Sub
Since textbox doesn't have a focus event, what you can do is set up one handler to handle all the textboxes' Enter event.
Enter Event Handler
Private Sub TextboxEnter(Sender As Object, E As EventArgs)
Dim FocusedTextbox As TextBox = DirectCast(Sender, TextBox)
FocusedTextBox.SelectAll
End Sub
Add the handler for each textboxes' Enter event
For Each tb As TextBox in Me.Controls.OfType(Of TextBox)
AddHandler tb.Enter, AddressOf TextBoxEnter
Next
If you need to filter the textboxes, use a common name pattern and use a conditional to check for that pattern in the Name property.

Edit Update DatagridView VB.Net (No Database)

Good day everyone.
I need your help in this project I am into (a Visual Basic program with no database.) It just contains a Datagridview, a Textbox, and three buttons (an "Add" Button, a "Edit" and an "Update" Button).
1 . Is there any way (like using "for loop") to automatically assign DataGridView1.Item("item location") to the one edited and be updated?
2 . Or is it possible to just click an item in the Datagridview then it will be edited at that without passing it to a Textbox, and to be updated at that.
The DataGridViewCellEventArgs variable (e in the method stub the designer will generate for you) of the double click event of the cell has RowIndex and ColumnIndex properties which refer to the position of the cell you clicked.
Save those (in a class variable possibly or a local one if that's all you need) and then refer to them when you update the cell in your DataGridView, possibly like this MyDataGridView.Item(e.ColumnIndex, e.RowIndex) or MyDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) where e is the variable from the double click event handler.
For you cell double click event you could have something like this:
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
Using myEditor As New frmCellEditor(Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value)
If myEditor.ShowDialog() = DialogResult.OK Then
Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = myEditor.NewCellValue
End If
End Using
End Sub
This will call a new instance of your editor and get a value from you. For the purpose of this demo I have made a form like this:
Public Class frmCellEditor
Public NewCellValue As Integer
Public Sub New(ByVal CurrentCellValue As Object)
InitializeComponent()
Me.TextBox1.Text = CStr(CurrentCellValue)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.NewCellValue = CInt(Me.TextBox1.Text)
Me.DialogResult = DialogResult.OK
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Call Me.Close()
End Sub
End Class
Which just has two buttons (Button1 = OK, Button2 = Cancel). When you click OK, it just returns the value 1 which then gets set as the value of the cell.
This is a VERY simplistic example, but it should provide you the basics of what you are trying to do.
UPDATE:
I updated the code for the editor interface so it will include handling for passing the value back and forth from the form with your datagridview.
In your project, make a new form called frmCellEditor. This forms has to have two buttons and a textbox (Make sure that the programmatic names match!). Replace the code with the code listed above. You will have to add Imports System.Windows.Forms above the class as well.
Amend the event handler for the cell double click event of your datagrid to pass the cell value when frmCellEditor is constructed (the line going ... New frmCellEditor(...).
How many columns does your DataGridView has?
Based on how you populate your DataGridView, I'll assume only 1.
Declare this on top of your form
Dim i as Integer
On your btnUpdate_Click Event (Just combine your Edit and Update button into One)
SELECT CASE btnUpdate.Text
Case "Update"
With DataGridView1
'Check if there is a selected row
If .SelectedRows.Count = 0 Then
Msgbox "No Row Selected for Update"
Exit Sub
End If
i = .CurrentRow.Index 'Remember the Row Position
Textbox1.Text = .item(0 ,i).value 'Pass the Value to the textbox
.Enabled = False 'Disable DataGridView to prevent users from clicking other row while updating.
btnUpdate.Text = "Save"
End With
Case Else 'Save
DatagridView1.Item(0,i).Value = Textbox1.Text
btnUpdate.Text = "Update"
END SELECT
Thanks for those who contributed to finding answers for this thread. I have not used your solutions for now (maybe some other time). After some research, I've found an answer for problem 2 (more user friendly at that):
2 . Or is it possible to just click an item in the Datagridview then
it will be edited at that without passing it to a Textbox, and to be
updated at that.
Here's what i did:
in Private Sub Form1_Load, just add:
yourDataGridView.EditMode = DataGridViewEditMode.EditOnEnter
in Private Sub yourDataGridView_(whatever event here: DoubleCellClick, CellContentClick, etc.) add:
DataGridView1(e.ColumnIndex, e.RowIndex).[ReadOnly] = False
DataGridView1.BeginEdit(False)

Delete Controls inside GroupBox

I created a groupbox and then populate it with buttons during runtime. I also created a button, say Button1 to loop through the groupbox and delete those buttons. Here's my code
for Button1:
Public Sub removeControls()
For Each ctrl As Control In GroupBox1.Controls
GroupBox1.Controls.Remove(ctrl)
ctrl.Dispose()
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
removeControls()
End Sub
When executed, it only removes some of the controls inside the GroupBox1, not all. Can you explain what is missing in my code to make it work? Thanks.
When you delete controls in a For Each loop, you're actually modifying the collection that you're trying to loop through. When you remove the first item in the collection, the second item moves up to become the first. But now, when you reach the second index of your loop, the third item is in its place. You've effectively skipped removing the second item, and only removed the first and third. And so on through the entire loop.
Instead, you need to loop through the controls in reverse order and remove the item at each index. By starting to removing items from the end, you won't affect the order or position of the items.
So, just change your method to the following:
Public Sub RemoveControls()
For i As Integer = (GroupBox1.Controls.Count - 1) To 0 Step -1
Dim ctrl As Control = GroupBox1.Controls(i)
GroupBox1.Controls.Remove(ctrl)
ctrl.Dispose()
Next i
End Sub
You are changing the collection as you are itterating through it, and that should not be done.
Rather use something like
For i As Integer = GroupBox1.Controls.Count - 1 To 0 Step -1
Dim ctrl As Control = GroupBox1.Controls(i)
GroupBox1.Controls.Remove(ctrl)
ctrl.Dispose()
Next