Datasource for every control in GroupBox - vb.net

Is something as this even possible. I'm pasting code bellow and hopping anyone could show me the right way to do it.
For Each tbbox As TableLayoutPanel In GroupBox3.Controls
'looping through all controls in my tablelayoutpanle
For Each ctl As Control In tbbox.Controls
If ctl.Name.StartsWith("cb_barva") Then
'im stuck here...
With (ctl)
.DataSource = ds_barve.Tables("moje_barve")
.DisplayMember = "barva"
.ValueMember = "barva"
.SelectedIndex = 0
End With
End If
Next
Next

You need the type conversion
With (ctl)
Convert the ctl to ComboBox
ctype(ctl,ComboBox)
If your not able to convert the control with "With" statement then change each line of your code like below....
ctype(ctl,ComboBox).DataSource = ds_barve.Tables("moje_barve")
ctype(ctl,ComboBox).DisplayMember = "barva"
ctype(ctl,ComboBox).ValueMember = "barva"
ctype(ctl,ComboBox).SelectedIndex = 0

Related

How to Use For Each cnt Loop to Target Specific Tags on Controls

I'm making a form that has a few hundred labels, and when a Clear button is clicked, I need to reset the text of specific labels to 0 while leaving other label's text alone. I don't want to use a group box because it will not look good with my current layout.
I'm trying to use the code:
For Each cnt In Me.Controls
If TypeOf cnt Is Label Then
CType(cnt, Label).Text = ""
End If
Which works fine for clearing every Label, but I want to specify a specific Tag as well. I tried
For Each cnt In Me.Controls
If TypeOf cnt Is Label And CType(cnt, Label).Tag = "ResetTo0" Then
CType(cnt, Label).Text = ""
End If
When I try to use this code, I get a cast exception error.
Does anyone know how I can add in my tag as well without getting a cast error, or a better way to do this?
Just use the extension OfType to get only labels and already of the right type
For Each cnt In Me.Controls.OfType(Of Label)
If cnt.Tag = "ResetTo0" Then
cnt.Text = ""
End If
Next
And if not all labels have the Tag property set then add also a check for Nothing
if cnt.Tag IsNot Nothing AndAlso cnt.Tag = "ResetTo0" Then
.....
End if
You can even try with a single line (albeit I suspect that this approach is not the best for clarity and performance)
Me.Controls.OfType(Of Label).
Where(Function(x) x.Tag = "ResetTo0").
ToList().
ForEach(Function(k) k.Text = "")

How do I fill the first empty TextBox in a GroupBox?

I have a GroupBox with multiple TextBox controls and I can check to see if any are empty just fine but I'm trying to make my program fill the first empty textbox it finds in the GroupBox.
Code:
Dim empty = From txt In grpbill.Controls.OfType(Of TextBox)()
Where txt.Text.Length = 0
If empty.Any Then
End If
Any ideas?
You're almost there. I'm unsure on how you define first but I've gone off the TabIndex property:
Dim firstEmptyTextBox As TextBox = (From txt In GroupBox1.Controls.OfType(Of TextBox)()
Where txt.Text.Length = 0
Order By txt.TabIndex Ascending).FirstOrDefault()
If firstEmptyTextBox IsNot Nothing Then
firstEmptyTextBox.Text = "Text"
End If
You can use the .FirstOrDefault() method:
Returns the first element of a sequence, or a default value if the sequence contains no elements.
In my example I have three TextBox controls. The first one has the text Not empty whilst the other two have nothing. When I run the code, this is my output:
Here another idea which will also work in cases where all TextBox controls in GroupBox are not empty.
Private Sub SetTextJForFirstEmptyTextBoxIfExists(text As String)
Dim emptyTextBoxes As IEnumerable(Of TextBox)
= grpbill.Controls.
OfType(Of TextBox)().
Where(Function(txtbox) txtbox.Text.Length = 0)
For Each emptyTextBox In emptyTextBoxes
emptyTextBox.Text = text
Exit Sub
Next
End Sub

Cannot clear this list

I'm getting the above error message on a DataGridView. This dgv is bound to a datatable. Below is the code that I use to check it.
If TypeOf ctl Is DataGridView Then
Dim ctl1 As DataGridView = DirectCast(ctl, DataGridView)
If Not IsNothing(ctl1.DataSource) = False Then
ctl1.DataSource = Nothing
Else
ctl1.Rows.Clear()
End If
End If
The code is taking the Else branch so I don't know why it's throwing this exception.
Are you sure it is taking the else branch?
If the DGV is databound the the Rows.Clear() will throw an exception.
Try changing the if statement to
If IsNothing(ctl1.Datasource) = False Then
You can clear the rows to what ctl1 DataGridView is pointing to instead of clearing ctl1 directly:
myDataTable.Rows.Clear()
See why i cannot clear the rows in the datagridview control?
Or,
https://www.codeproject.com/Questions/332902/how-to-clear-datagridview-in-csharp

Need to change Datagridview row color if checkbox is checked on Form Load

i have problem with dataset gridview on Form load procedure. I hava dataset as datagridview source and when I'm trying to change datagrid row color based on if statement if checkbox is checked nothing happens. If I used same code on some button-click procedure it all works fine.
Can anyone help me with this problem.
da.Fill(ds, "customer")
cnn.Close()
DataGridView1.DataSource = ds.Tables("customer")
For i = 0 To DataGridView1.Rows.Count - 1
If DataGridView1.Rows(i).Cells(3).Value = True Then
DataGridView1.Rows(i).DefaultCellStyle.BackColor = Color.MediumAquamarine
Else
DataGridView1.Rows(i).DefaultCellStyle.BackColor = Color.MistyRose
End If
Next
You cant have this code in Form_Load. This only occur when the form starts the first time. Try instead to put the code in the DataGridView1.Paint event handler. That should do the trick.

Looping through Controls in VB.NET

I am creating a chess program. And it is composed of sixty four picture boxes with alternating black and white background colours.
I have named them pba1, pba2, pbb1, pbb2, pbc1 and so on.
Now, I want to loop through only the black ones, for example, I want to loop through only, pba1, pbb2, pbc3 and so on.
How do I create a loop for this in VB.NET?
I know of the way to loop through similarly named controls, but I am not able to adapt that method for my problem. Can you tell me a solution?
EDIT: In pba1, pb stands for picture box, and a1 stands for the square. Just in case, you wonder why such a name.
EDIT: Check out this answer
Loop through the PictureBox's in your ControlCollection and test for BackColor. I used the Form's ControlCollection, if they are in some other type of container control use that.
For Each cntrl As Control In Me.Controls
If TypeOf cntrl Is PictureBox Then
If cntrl.BackColor = Color.Black Then
'Do Something
End If
End If
Next
Base on the additional information that you gave in your answer, the reason your example is not working is that the Controls Name is a String and you are comparing it to the PictureBox Control not the Name of the Control.
You can try using the Tag Property instead of the Name of the Control, it will be cleaner and easier to read. I just put a 1 in the PictureBox's Tag Property for Black and a 0 for White.
Private Sub OriginalColour()
For Each cntrl As Control In Me.Controls
Dim result As Integer
If TypeOf cntrl Is PictureBox Then
If Integer.TryParse(cntrl.Tag.ToString, result) Then
If result = 1 Then
cntrl.BackColor = Color.Gray
Else
cntrl.BackColor = Color.White
End If
End If
End If
Next
End Sub
Generating controls at design time via the Forms Designer only makes sense for layouts which benefit from the forms designer.
In your case, you just have 64 uniform boxes in 8 rows of 8. Don’t use the Forms Designer for this, create the controls at runtime, and don’t give them names like pba1, just put them into an appropriate data structure (such as an 8x8 array):
Private chessFields As PictureBox(8, 8)
' In Form_Load:
For i = 0 To 7
For j = 0 To 7
chessFields(i, j) = New PictureBox
' Set size, position … then, finally,
Controls.Add(chessFields(i, j))
Next
Next
That way, you can access the fields in an orderly fashion without having to go via the Form.Controls collection.
Put all the pictureboxes in an 8x8 tableLayoutPanel (also useful for scaling etc). Then
For Each pb As PictureBox In TableLayoutPanel1.Controls
Dim col As Integer = TableLayoutPanel1.GetCellPosition(pb).Column
Dim row As Integer = TableLayoutPanel1.GetCellPosition(pb).Row
If col Mod 2 = 0 Xor row Mod 2 = 0 Then
pb.BackColor = Color.Black
Else
pb.BackColor = Color.White
End If
Next
Of course you could also use an array of the squares if you have that available.
This will not affect the events (pba1.click etc).
This is fairly simple and it may be resource heavy, but it works. I have a form with 36 CheckBoxes. This takes advantage of the fact that when you copy a checkbox it just increases the number of the name. I ended up with 36 checkboxes named CheckBox1 thru Checkbox36. The Function returns a checkbox, which may be used to set or read any property.
Private Function GetCheckBox(ByVal Index As Integer) As CheckBox
Dim CKBox As checkbox
For Each cntrl As Control In Me.Controls
If TypeOf cntrl Is CheckBox Then
CKBox = cntrl
If CKBox.Name = "CheckBox" & Index Then
Exit For
End If
End If
Next
Return ckbox
End Function