In Microsoft Access, when you click on a label, the textbox associated with that label gets the focus. As far as I can tell, VB.NET does not have this same functionality. I know I can always add something in to the click event of the label, like so...
TextBox1.Focus()
But I have dozens of fields on the form, and it would make it so much easier if I did not need to add this to the click event of each label.
I guess it would be possible to make an event for all labels that forces a tab to the next control, and assuming that I have the Tab indices set up correctly, then this would work. The problem would occur when adding new fields to the form, in which case all tab indices would need re-verified.
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click
'code to tab to next field...
End Sub
Is there any easier way?
First, set the controls' TabIndex orders on your form then use this code:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each c As Control In Me.Controls
If TypeOf c Is Label Then AddHandler c.Click, AddressOf Label_Click
Next
End Sub
Private Sub Label_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Me.SelectNextControl(sender, True, True, True, True)
End Sub
End Class
Now whenever you click on a label, the following control in the order will be focused.
How about creating a dictionary where the label is the key and the control to focus is the value, then add a Click event handler to all of the label in the Dictionary. Everytime you add a label/control 'all' you need to do is add another KeyValuePair to the Dictionary
Simple Example:
Public Class Form1
Protected Friend DicLabelToControl As Dictionary(Of Label, Control)
Protected Friend Sub InitLabelDic()
DicLabelToControl = New Dictionary(Of Label, Control) From {{Label1, TextBox1}, {Label2, TextBox2}}
End Sub
Protected Friend Sub AddClickEventsToLabels()
For Each lb As Label In DicLabelToControl.Keys
AddHandler lb.Click, AddressOf HandleLabelClick
Next
End Sub
Private Sub HandleLabelClick(sender As Object, e As EventArgs)
DicLabelToControl(CType(sender, Label)).Focus()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitLabelDic()
AddClickEventsToLabels()
End Sub
End Class
Related
Currently, I have this, on my Form.vb:
Private Sub txtBox1_Leave(sender As Control, e As EventArgs) Handles txtBox1.Leave
'Some code
End Sub
...
Private Sub txtBox10_Leave(sender As Control, e As EventArgs) Handles txtBox10.Leave
'Some code
End Sub
The thing that bothers me is: All those events are doing the same thing. Is it possible to programatically have a list of the relevant controls and iterate through them, adding such events? This would allow me to reduce the amount of code in my application / coding effort. Something like:
For Each c As Control in listOfControls
'Add event for c here which calls method
Next
I really think there is a simple way of doing that but everything I've tried so far (such as AddHandler) did not work. Any ideas?
Thank you
Yes it is possible and quite simple, create a method that will add the requested event to the Control, pass an array of controls to that method before the form loads:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' add events to all requested controls
AddEvent(New Control() {TextBox1, TextBox2, TextBox3, Button1})
End Sub
Public Sub AddEvent(ByVal myControls() As Control)
For Each c As Control In myControls
AddHandler c.Leave, AddressOf Control_Leave
Next
End Sub
Private Sub Control_Leave(sender As Object, e As EventArgs)
MsgBox("Control is not in focus")
End Sub
End Class
I have created a game in visual basic, and have decided to expand by adding multiple rooms on the game. Each room will be a panel that shows when the user enters a certain area. To start, I created a class that inherits panel properties, then added it to my main Form. I then added all the items to the panel controls. My issue is that i cannot control the player when it is in the panel controls. I have tried all sorts, but couldn't get it to work.
I did some reading and found that panel does not come with keyUp() and keyDown() events. However, I would like to know if there is a way round this.
Thanks in advance!
Code of mainRoom() class (my panel):
Public Class mainRoom
Inherits Panel
Sub New()
With Me
.SetBounds(0, 0, Form1.Width, Form1.Height)
.SendToBack()
End With
End Sub
Public Sub mainRoom_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
e.Graphics.FillRectangle(Brushes.DarkOrange, block)
End Sub
End Class
In main form class:
Sub setMap()
main = New mainRoom()
Me.Controls.Add(main)
End Sub
You can set the KeyPreview=True on the main form, and then handle the key up/down events from the form:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
'key down code.
e.Handled = True
End Sub
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles MyBase.KeyUp
'key up code.
e.Handled = True
End Sub
Note: if you don't want other controls' key up/down event handlers to fire after your form event handlers do, then set e.Handled=True as I have in the above example.
See MSDN for more info on KeyPreview.
BEWARE - when moving (cut/paste) existing controls via the IDE from a form into a new panel control, the event handlers are not carried across as they become children of the parent control (the new panel). So this happens:
Private Sub Button1_Click(sender As Object, e As EventArgs)
Add the event handlers back and don't spend an age googling why keypress events suddenly stop firing in panels ...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
I have a combobox in a form1 and a datagridview in another form2.
I want to get the combobox selected with a value from the datagridview in the second form
I use the code below in form2 and it works:
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
form1.CBO_fournisseur.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
Me.Close()
End Sub
But what I want to do is that the name of the form is passed dynamically to avoid using and IFELSE clause to enumerate all the forms I have in my project that use form2
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
If formbon2.Name = "FRM_BN_RECEPTION_CUIR" Then
FRM_BN_RECEPTION_CUIR.CBO_fournisseur.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
ElseIf formbon2.Name = "frm_reception_acc_provisoire" Then
frm_reception_acc_provisoire.CBO_1.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
End If
Me.Close()
End Sub
I think I've got what you want to do. I strongly suggest you stop using the Form as a Shared resource.
Use a constructor like this in your Form2:
Private ParentFormCombo as Combobox
Public Sub New(ByVal pCmb as Combobox)
ParentFormCombo = pCmb
End Sub
Then in your doubleclick you just change the text of ParentFormCombo
ParentFormCombo.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
Then you have to stop using:
FrmList_View.Show()
Now you should always use the constructor instead (New()). So do the following instead:
Dim f As New FrmList_View(CBO_fournisseur)
'or
Dim f As New FrmList_View(CBO_1)
f.Show()
I need help in my VB.NET project. I declare a dynamic textbox which is "dim textbox as new textbox()" inside the button and it will create a new textbox when I press button1 and I also put text on the new textbox created. Now when a dynamic textbox already created. When I press button2 I want to compare the text on the label to the text in dynamic textbox created but I got an error that says, OBJECT REFERENCE NOT SET AN INSTANCE OF AN OBJECT.
I suppose you create the textbox in the click event handler of the button. this way, you can only access it in this event handler method. In order to use it in the other event handler, you need to move the declaration to class level, e.g.:
Private txtBox As Textbox
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
txtBox = New Textbox()
' ...
Me.Controls.Add(txtBox)
End Sub
Private Sub btn2_Click(sender As Object, e As EventArgs) Handles btn2.Click
If txtBox IsNot Nothing Then
MsgBox(txtBox.Text)
End If
End Sub
Try it like this. You have to store the reference to your textbox in a variable, e. g. in the scope of the form instance.
Public Class Form1
Private dynTextbox As TextBox
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Me.dynTextbox = New TextBox
With Me.dynTextbox
.Top = Me.Button1.Top
.Left = Me.Button1.Right + 5
.Text = "test"
End With
Me.Controls.Add(Me.dynTextbox)
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
If Me.dynTextbox IsNot Nothing Then MessageBox.Show(Me.Label1.Text = Me.dynTextbox.Text)
End Sub
End Class
If you create multiple textboxes dynamically, you may store them in some Array or List (e. g. in a List(Of TextBox)) and then you'll have to find a way to reference the one you need, that depends on your specific project.
I have created a User Control and would like to be able to detect when the user clicks on the Form.
I have seen this question which is related but the suggestion to use the the Leave event doesn't always do what I want because the focus doesn't necessarily change when the user clicks the Form (my control could be the only control on the Form in which case focus stays with my control).
Any ideas?
I want to be able to do something like this from within the User Control:
Private Sub ParentForm_Click(sender As Object, e As System.EventArgs) _
Handles Me.Parent.Click
End Sub
I would do it slightly differently:
Private _form As Control
Private Sub UserControl_ParentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ParentChanged
If _form IsNot Nothing Then
RemoveHandler _form.Click, AddressOf ParentOnClick
End If
_form = Me.FindForm()
If _form IsNot Nothing Then
AddHandler _form.Click, AddressOf ParentOnClick
End If
End Sub
Private Sub ParentOnClick(ByVal sender As Object, ByVal e As EventArgs)
'...
End Sub
This gives it a little more resillience - if it is not a direct child of a Form, if its parent changes etc.
I figured out how to do this myself - for anyone interested I am doing the following:
Private _parentForm As Form
Private Sub UserControl_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
_parentForm = CType(Parent, Form)
AddHandler _parentForm.Click, AddressOf ParentForm_Click
End Sub
Private Sub ParentForm_Click(sender As Object, e As System.EventArgs)
debug.writeline("Parent form clicked")
End Sub