Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am having problem with emptying every TextBoxes inside a GroupBox, because my loop only clears all TextBoxes if textbox1 has value but if I try to bypass textbox1 and jump to input data to textbox2, my ClearCtrlText method doesn't work.
Please see my loop code if there's a need for change:
Public Sub ClearCtrlText(ByVal root As Control)
For Each ctrl As Control In root.Controls
If TypeOf ctrl Is TextBox Then ' textbox set to empty string
If ctrl.Text <> "" Then
ctrl.Text = Nothing
End If
End If
Next
End Sub
I would be tempted to write this as an extension method:
Imports System.Runtime.CompilerServices
Public Module ControlExtensions
<Extension>
Public Sub ClearTextBoxes(source As Control)
For Each child As Control In source.Controls
Dim tb = TryCast(child, TextBox)
If tb Is Nothing Then
child.ClearTextBoxes()
Else
tb.Clear()
End If
Next
End Sub
End Module
You can then call it on a control as though it was a member, e.g.
GroupBox1.ClearTextBoxes()
This method also includes the recursion required to access child controls inside child containers, e.g. a Panel inside the GroupBox.
You need to RECURSE into containers within the form like this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ClearCtrlText(Me)
End Sub
Public Sub ClearCtrlText(ByVal root As Control)
For Each ctrl As Control In root.Controls
If TypeOf ctrl Is TextBox Then ' textbox set to empty string
If ctrl.Text <> "" Then
ctrl.Text = Nothing
End If
ElseIf ctrl.HasChildren Then
ClearCtrlText(ctrl)
End If
Next
End Sub
End Class
Related
I've created a custom control that need to be initialized. Actually I have that function to initialize my custom control (called "UserControl_Grille") :
Private Sub Init_Grille()
Me.grilleA.init_traduction(lignesTraduction)
Me.grilleB.init_traduction(lignesTraduction)
Me.grilleC.init_traduction(lignesTraduction)
Me.grilleD.init_traduction(lignesTraduction)
Me.grilleE.init_traduction(lignesTraduction)
Me.grilleF.init_traduction(lignesTraduction)
Me.grilleG.init_traduction(lignesTraduction)
Me.grilleH.init_traduction(lignesTraduction)
End Sub
As you can see it's not very worth it as If a add a new control I have to add it in this function.
So I tried to initialize automatically but it seems that it don't detect any custom control in my form ... :
Private Sub Init_Grille()
For Each grille As UserControl_Grille In Me.Controls.OfType(Of UserControl_Grille)()
grille.init_traduction(lignesTraduction)
Next
End Sub
In debug mode, it direct pass throught the For Each loop. There is any other solution?
You can recursively scroll through all controls.
For example, this sample code will return a list of all Labels in your form:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' This list will hold all the labels that we find
Dim results As List(Of Control) = New List(Of Control)
' Start searching for labels at the Form level
FindControls(Me, results)
' See how many labels we have found
MessageBox.Show(results.Count)
End Sub
Private Sub FindControls(parent As Control, ByRef results As List(Of Control))
For Each control As Control In parent.Controls
If TypeOf control Is Label Then
' We found a label so we add it to the results
results.Add(control)
End If
If Not control.Controls Is Nothing Then
' We loop through all sub-controls
FindControls(control, results)
End If
Next
End Sub
End Class
Hope this helps :)
On a VB.NET project with Metroframework Modern UI 1.4.0.0 installed, I use this part of code into a Module to loop over all MetroTextBoxes which placed into a MetroTabControl and give Cursor.Hand to their embedded Clear button. How can I do the same thing including MetroTextBoxes which could be out of MetroTabControl, into my form or into an other container for example? In other words, I would like to loop over every MetroTextBox into a form, even if it is nested.
Public Sub TxtBoxes_Cursors(sender, e)
Dim _FormSender = DirectCast(sender, MetroFramework.Forms.MetroForm)
For Each _MetroTabControl As Control In _FormSender.Controls.OfType(Of MetroFramework.Controls.MetroTabControl)()
For Each _TabPage As Control In _MetroTabControl.Controls.OfType(Of MetroFramework.Controls.MetroTabPage)()
For Each _Textbox As Control In _TabPage.Controls.OfType(Of MetroFramework.Controls.MetroTextBox)()
If _Textbox.HasChildren Then
For Each _ClearButton As Control In _Textbox.Controls
If _ClearButton.Name = "lnkClear" Then
_ClearButton.Cursor = System.Windows.Forms.Cursors.Hand
End If
Next
End If
Next
Next
Next
End Sub
This is the exact answer to my question according to the accepted answer of this relevant question which user A Friend pointed on comments. First I have to place this Function into my Module:
Public Function FindControlRecursive(ByVal list As List(Of Control), ByVal parent As Control, ByVal ctrlType As System.Type) As List(Of Control)
If parent Is Nothing Then Return list
If parent.GetType Is ctrlType Then
list.Add(parent)
End If
For Each child As Control In parent.Controls
FindControlRecursive(list, child, ctrlType)
Next
Return list
End Function
And then edit my Public Sub like this:
Public Sub TxtBoxes_Cursors(sender, e)
Dim _FormSender = DirectCast(sender, MetroFramework.Forms.MetroForm)
Dim _MetroTextBoxes As New List(Of Control)
For Each _Textbox As MetroFramework.Controls.MetroTextBox In FindControlRecursive(_MetroTextBoxes, _FormSender, GetType(MetroFramework.Controls.MetroTextBox))
If _Textbox.HasChildren Then
For Each _ClearButton As Control In _Textbox.Controls
If _ClearButton.Name = "lnkClear" Then
_ClearButton.Cursor = System.Windows.Forms.Cursors.Hand
End If
Next
End If
Next
End Sub
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.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have an application migrated from vb6 to vb.net.
I want to access the text of textbox1 in SearchFields of module.
I do not want to pass it as a parameter because I have so many controls to pass.
Please provide some example.
My code is frmNew page have Textbox1
Private Sub Ok_Click(.....)
call SearchFields()
Me.Close()
End Sub
Inside module I have method below
Sub SearchFields()
Dim str As string
Dim frm As New frmNew
str = frm.Textbox1.Text
End Sub
frmNew.Textbox1.Text is getting nothing
To do as little recoding as possible, you can change your two methods to the following. For this to work Textbox1 must be marked public. I have personally had to "migrate" VB6 apps to .Net, as #LarsTech pointed out, this requires rethinking of your app, not just syntax changes.
Private Sub Ok_Click(.....)
call SearchFields(Me)
Me.Close()
End Sub
Sub SearchFields(Form frm)
Dim str As string
str = frm.Textbox1.Text
End Sub
You can pass a reference to the control to use for the search text. This makes your SearchFields method more general. As an example, I created a form named frmNew and a module named Searching. On the form I placed a button named Ok, a TextBox and a ComboBox.
Public Class frmNew
Private Sub Ok_Click(sender As Object, e As EventArgs) Handles Ok.Click
Searching.SearchFields(TextBox1)
Searching.SearchFields(ComboBox1)
Me.Close()
End Sub
End Class
There are two ways you could go about handling the control passed to the module (which I named Searching). First, you can check the type of the control and take actions based on that:
Module Searching
Sub SearchFields(textSource As Control)
Dim str As String = ""
' just for invesigating, show the type of the control.
Console.WriteLine(TypeName(textSource))
If TypeOf textSource Is System.Windows.Forms.TextBox Then
str = textSource.Text
ElseIf TypeOf textSource Is System.Windows.Forms.ComboBox Then
Dim src = DirectCast(textSource, ComboBox)
If src.SelectedIndex >= 0 Then
str = src.SelectedItem.ToString()
Else
' nothing was selected. Do whatever is appropriate.
str = "NOTHING SELECTED!"
End If
End If
'TODO: the searching code.
Console.WriteLine(str)
End Sub
End Module
Alternatively, you can take advantage of method overloading, where it runs the version of the method which corresponds to the argument(s) you pass to it:
Module Searching
Sub SearchFields(src As TextBox)
DoSearch(src.Text)
End Sub
Sub SearchFields(src As ComboBox)
'TODO: check an item is selected.
Dim txt = src.SelectedItem.ToString()
DoSearch(txt)
End Sub
Private Sub DoSearch(s As String)
' do the search
Console.WriteLine(s)
End Sub
End Module
I am fairly new to vb.net and would like to be able to access the value (such as .text on a textbox) from another an open form. In my application I open a form from my main form, and when I try to access the text in the controls on the main form I am unable to see the .text value on the control.
I can loop through all controls on the main form just fine, but when I want to see the actual values, all controls are empty. My controls such as text boxes and combo boxes are inside of a tab control and group boxes.
Is there a way to make all .text or values on the open form available from the other open form?
Here is how I am looping through the controls on the main form.
Try
For Each Tp As TabPage In UserData.UserTabControl.TabPages
'Name of Tabcontrol is UserTabcontrol
For Each gbx As GroupBox In Tp.Controls
For Each ctrl As Control In gbx.Controls
If ctrl.Name = "UserName" Then
MsgBox(UserData.UserName.Text) 'Messagebox here is empty
End If
Next ctrl
Next gbx
Next Tp
Me.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Thanks in advance.
Chris
From the example you've given you already have access to a reference to your Control. Instead of going back to the Form and trying to access that control as a property of the Form you could just cast your reference and call its Text property directly.
If ctrl.Name = "UserName" Then
MsgBox(DirectCast(ctrl, TextBox).Text) 'Assuming your UserName control is a TextBox
End If
If you would like to reference controls on an open form, call it Form1:
First add a Form1 property or variable to the calling form:
Public Class Form2
Public Property f1 As Form1
...
Private Sub DoSomething()
MsgBox("Here's some text from Form1: " & f1.Textbox1.Text)
End Sub
End Class
In the callee form, set the Form2 property to the form object:
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Form2.f1 = Me
Form2.ShowDialog() ' or Form2.Show()
End Sub
End Class
You can then reference all Form1 objects from Form2 using the f1 property.
By this command, I could change the amount of control in another form.
My.Forms.myForm.labelControl.Text = "bela"
Please try this :
MsgBox(My.Forms.UserData.UserName.Text)