i currently have multiple forms (around 30 forms) and i am switching between forms. The Main form (Form1) has 29 buttons and each button will take me to the respective form number (example: button3 = form3, button20=form20, etc).
I understand that I can use the code:
me.hide
form1.show
I want a method to pass the form name dynamically, something along the lines of:
me.controls(FormName).show
Is this possible?
Create a new project with three forms (Form1, Form2, and Form3). Put two buttons on Form1 (named Button2 and Button3), then place the following source code in Form1:
Option Strict On
Public Class Form1
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Call FormFromButton(DirectCast(sender, Button))
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Call FormFromButton(DirectCast(sender, Button))
End Sub
Public Sub FormFromButton(btn As Button)
Dim i As Integer = CInt(btn.Name.Substring(6)) 'Get number after "button" (6 characters)
Dim f As Form = GetForm("Form" & i.ToString)
f.Show()
f.Activate()
End Sub
Public Function GetForm(formClassName As String) As Form
'see if it is already instanced
For Each f As Form In My.Application.OpenForms
If f.GetType.Name = formClassName Then Return f
Next f
'create new instance
Dim strFullName As String = Me.GetType.Namespace & "." & formClassName
Dim o As Object = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(strFullName)
Dim frm As Form = DirectCast(o, Form)
Return frm
End Function
End Class
Myself created 4 forms one is parent another 3(Form3,Form4,Form5) is child and i was created 3 buttons in parent form and that button Text is Form3,Form4,Form5
Imports System
Imports System.Reflection
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is Button Then
Dim btn As Button
btn = DirectCast(ctrl, Button)
AddHandler btn.Click, AddressOf Me.buttonclick
End If
Next
End Sub
Private Sub buttonclick(sender As Object, e As EventArgs)
Dim frmname As Button = DirectCast(sender, Button)
Dim frmAssembly As Assembly = Assembly.LoadFile(Application.ExecutablePath)
For Each type As Type In frmAssembly.GetTypes
If type.BaseType = GetType(Form) Then
If (type.Name = frmname.Text) Then
Dim frmshow As Form = DirectCast(frmAssembly.CreateInstance(type.ToString()), Form)
For Each frm As Form In Me.MdiChildren
frm.Close()
Next
frmshow.Show()
End If
End If
Next
End Sub
End Class
Private Sub ButtonClick(ByVal sender As Object, e As System.EventArgs)
Dim btn As Button = DirectCast(sender, Button)
Dim formname As String = "form" & btn.Name(btn.Name.Length - 1)
Dim frm As Form = GetForm(formname)
frm.Show()
End Sub
Private Function GetForm(ByVal Formname As String) As Form
Dim t As Type = Type.GetType(Formname) ', True, True)
If t Is Nothing Then
Dim Fullname As String = Application.ProductName & "." & Formname
t = Type.GetType(Fullname, True, True)
End If
Return CType(Activator.CreateInstance(t), Form)
End Function
Private Sub AddHandlers()
AddHandler Button1.Click, AddressOf ButtonClick
AddHandler Button2.Click, AddressOf ButtonClick
AddHandler Button3.Click, AddressOf ButtonClick
AddHandler Button4.Click, AddressOf ButtonClick
End Sub
Private Sub RemoveHandlers()
RemoveHandler Button1.Click, AddressOf ButtonClick
RemoveHandler Button2.Click, AddressOf ButtonClick
RemoveHandler Button3.Click, AddressOf ButtonClick
RemoveHandler Button4.Click, AddressOf ButtonClick
End Sub
Private Sub Form2_Activated(sender As Object, e As System.EventArgs) Handles Me.Activated
AddHandlers()
End Sub
Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
RemoveHandlers()
End Sub
Related
I want to disable the mousewheel to prevent scrolling in the ComboBoxes.
For one ComboBox this works:
Private Sub CmbDienst_MouseWheel(sender As Object, e As MouseEventArgs) Handles CmbDienst.MouseWheel
Dim HMEA As HandledMouseEventArgs = DirectCast(e, HandledMouseEventArgs)
HMEA.Handled = True
End Sub
But how can I add this to ALL ComboBoxes? There are a lot of them in the form.
I was looking for something like
Private Sub Combo_Mouse()
For Each c As Control In Me.Controls.OfType(Of ComboBox)()
'And then...?
Next
End Sub
Thanks!
It works. The problem I had was that the comboboxes are in several containers, such as Panels and Datagridviews. Then is "me.controls, etc" not enough.
So I finally made this out of it:
In the Form load:
EnumControls(Me)
In the Programm:
Private Sub ComboBoxes_MouseWheel(sender As Object, e As MouseEventArgs)
Dim hmea = DirectCast(e, HandledMouseEventArgs)
hmea.Handled = True
End Sub
Private Sub EnumControls(ByVal ctl As Control)
If ctl.HasChildren Then
For Each c As Control In ctl.Controls
For Each comboBox In c.Controls.OfType(Of ComboBox)()
AddHandler comboBox.MouseWheel, AddressOf ComboBoxes_MouseWheel
Next
EnumControls(c)
Next
End If
End Sub
It works. Suggestions are welcome!
Try this
Private Sub buttonHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim mwe As HandledMouseEventArgs = DirectCast(e, HandledMouseEventArgs)
mwe.Handled = True
End Sub
and in FormLoad
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each c As Control In Me.Controls.OfType(Of ComboBox)()
'You cann acces to ComboBox her by c
AddHandler c.MouseWheel, AddressOf buttonHandler
Next
End Sub
I'm a newbie to Visual Basic and I have this code over here that's been bugging me. I can't think of another way to simplify this. Can you please help? Thanks!:
Private Sub PictureBox_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click,
PictureBox2.Click, PictureBox3.Click, PictureBox4.Click, PictureBox5.Click, PictureBox6.Click,
PictureBox7.Click, PictureBox8.Click, PictureBox9.Click, PictureBox10.Click, PictureBox11.Click,
PictureBox12.Click, PictureBox13.Click, PictureBox14.Click, PictureBox15.Click, PictureBox16.Click,
PictureBox17.Click, PictureBox18.Click, PictureBox19.Click, PictureBox20.Click, PictureBox21.Click,
PictureBox22.Click, PictureBox23.Click, PictureBox24.Click, PictureBox25.Click, PictureBox26.Click,
PictureBox27.Click, PictureBox28.Click, PictureBox29.Click, PictureBox30.Click, PictureBox31.Click,
PictureBox32.Click, PictureBox33.Click, PictureBox34.Click, PictureBox35.Click, PictureBox36.Click,
PictureBox37.Click, PictureBox38.Click, PictureBox39.Click, PictureBox40.Click, PictureBox41.Click,
PictureBox42.Click, PictureBox43.Click, PictureBox44.Click, PictureBox45.Click, PictureBox46.Click,
PictureBox47.Click, PictureBox48.Click, PictureBox49.Click, PictureBox50.Click, PictureBox51.Click,
PictureBox52.Click, PictureBox53.Click, PictureBox54.Click, PictureBox55.Click, PictureBox56.Click,
PictureBox57.Click, PictureBox58.Click, PictureBox59.Click, PictureBox60.Click, PictureBox61.Click,
PictureBox62.Click, PictureBox63.Click, PictureBox64.Click
...............
............... (stuff is down here.)
...............
...............
End Sub
You will need to store the lists in a collection of some sort. This can either be an array or a List(Of PictureBox) or if all of the controls have the same parent you can simply leverage the Controls property.
Once you have the collection in place, you will need to iterate over collection and use AddHandler to reference. Inside the referenced method, you would get the sender, and convert it to a PictureBox.
Here is an example assuming all the PictureBox controls are on the Form:
Private Sub Form1_Load(sender As Object, e As EventArgs)
For Each pb In Controls.OfType(Of PictureBox)()
AddHandler pb.Click, AddressOf pb_Click
Next
End Sub
Private Sub pb_Click(sender As Object, e As EventArgs)
Dim pb = DirectCast(sender, PictureBox)
' pb is the control that was clicked
End Sub
Here's how to build a list of the pictureboxes, with them "in order", assuming they are already on the form:
Public Class Form1
Private PBs As New List(Of PictureBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 1 To 64
Dim ctlName As String = "PictureBox" & i
Dim ctl As Control = Me.Controls.Find(ctlName, True).FirstOrDefault
If Not IsNothing(ctl) AndAlso TypeOf ctl Is PictureBox Then
Dim pb As PictureBox = DirectCast(ctl, PictureBox)
AddHandler pb.Click, AddressOf PB_Click
PBs.Add(pb)
Else
MessageBox.Show("Unable to find " & ctlName)
End If
Next
End Sub
Private Sub PB_Click(sender As Object, e As EventArgs)
Dim pb As PictureBox = DirectCast(sender, PictureBox)
' ... do something with pb ...
End Sub
End Class
From the comments:
Wait a minute, how do I do For Each pb In Controls.OfType(Of
PictureBox)() AddHandler pb.Click, AddressOf pb_Click Next But for a
List(Of Picturebox) named "Formula"?
For Each pb As PictureBox in Formula
AddHandler pb.Click, AddressOf pb_Click
Next
Here's what you code produces after turning on the BorderStyle:
Got a UserControl designed with several Labels and PictureBoxes.
Now I do integrate this UserControl via Controls.Add to a Panel where they get displayed the main Form1.
Now I like to raise an event once a UserControll is clicked or hovered.
If I do it via AddHandler taskItem.MouseClick, AddressOf meClick but its only triggered when I click the empty space of this Usercontrol and not on a label or PictureBox.
The goal is to use the Event to remove the clicked UserControl from the Label.
EDIT:
This is how my UserControl looks like:
Public Class Taks
Private Sub Taks_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each childControl As Control In Controls
AddHandler childControl.MouseClick, AddressOf Form1.meClick
Next
End Sub
Public Sub AddTasks(ByVal task_label As TaskLabels, ByVal show_seperator As Boolean, ByVal task_subject As String, ByVal task_message As String)
taskTitel.Text = task_subject
taskDesc.Text = task_message
If task_label = TaskLabels.General Then
taskImage.Image = My.Resources.Information_50px
End If
If task_label = TaskLabels.Important Then
taskImage.Image = My.Resources.Error_48px
End If
If task_label = TaskLabels.Critical Then
taskImage.Image = My.Resources.Box_Important_50px
End If
BunifuImageButton1.Hide()
End Sub
Enum TaskLabels
General = 0
Important = 1
Critical = 2
End Enum
End Class
And here I integrate the UserControl into a panel
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddTasks(Taks.TaskLabels.Critical, False, "Batterie Spannung", "low power")
AddTasks(Taks.TaskLabels.Important, False, "Wetter", "Das Wetter hat sich verschlechtert, Wind > 15km/h")
AddTasks(Taks.TaskLabels.General, False, "Server", "Auslastung liegt bei 12%")
AddTasks(Taks.TaskLabels.Important, False, "Temperature", "Temperatur der Proben im Kritischen Bereich")
End Sub
Sub AddTasks(ByVal taksLabels As Taks.TaskLabels, ByVal task_sep As Boolean, ByVal taskTitle As String, ByVal TaskDesc As String, Optional ByVal toFront As Boolean = False)
Dim taskItem As New Taks
taskItem.AddTasks(taksLabels, task_sep, taskTitle, TaskDesc)
taskItem.Dock = DockStyle.Top
AddHandler taskItem.MouseClick, AddressOf meClick
taskItem.Cursor = Cursors.Hand
Panel1.Controls.Add(taskItem)
End Sub
Public Sub meClick(sender As Object, e As MouseEventArgs)
If MessageBox.Show("delete Event?", "Question", MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.Yes Then
Panel1.Controls.Remove(sender)
End If
BunifuVScrollBar1.Maximum = Panel1.Height
End Sub
End Class
That's how events work. It's just like how a form doesn't raise a Click event when you click a Button on it. If you want the UC to raise a MouseClick event when a child control is clicked on then you need to handle the event of the child control internally and then raise the UC's event yourself. E.g.
Public Class UserControl1
Private Sub UserControl1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each childControl As Control In Controls
'Filter specific control types if desired.
If TypeOf childControl Is Label OrElse TypeOf childControl Is Panel Then
AddHandler childControl.MouseClick, AddressOf ChildControls_MouseClick
End If
Next
End Sub
Private Sub ChildControls_MouseClick(sender As Object, e As MouseEventArgs)
Dim childControl = DirectCast(sender, Control)
'Translate location on child control to location on user control.
Dim translatedLocation = PointToClient(childControl.PointToScreen(e.Location))
Dim args As New MouseEventArgs(e.Button,
e.Clicks,
translatedLocation.X,
translatedLocation.Y,
e.Delta)
'Raise the event of the user control.
OnMouseClick(args)
End Sub
End Class
I could easily close form after few seconds; but when I want to close many forms one after another, same sequence as they were "created"; I could not figure it out:
The main form code is as below:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfForms As Integer = 10
For open = 1 To numberOfForms
TestClosing()
Next
End Sub
The module code that I am trying to create then close forms after few seconds is as below:
Imports System.Timers
Module ClosingModule
Sub TestClosing()
Dim frmNew As New Form
frmNew.Show()
Dim tmr As New System.Timers.Timer()
tmr.Interval = 3000
tmr.Enabled = True
tmr.Start()
End Sub
End Module
I started a timer, but all the methods I tried to close the form is same sequence they were created; were not successful;
Help appreciated; and thanks in advance.
Add the Timer to the Forms you are creating, start it when the Form is created that way they will be closed in the same order that they were created. I also added an incremental delay to that the order of closing is more evident.
Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim numberOfForms As Integer = 10
For open = 1 To numberOfForms
Dim frmNew As New Form2
frmNew.Text = open.ToString
frmNew.Show()
Next
End Sub
Form2
Public Class Form2
Dim myTimer As New Timer()
Private Sub myTimer_Tick(sender As System.Object, e As System.EventArgs)
myTimer.Stop()
Me.Close()
End Sub
Private Sub Form2_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
myTimer.Interval = 1000 * CInt(Me.Text)
AddHandler myTimer.Tick, AddressOf myTimer_Tick
myTimer.Start()
End Sub
End Class
Added code in module to do the same thing:
Imports System.Timers
Module ClosingModule
Sub TestClosing(multiplier As Integer)
Dim frmNew As New Form
frmNew.Show()
Dim tmr As New System.Timers.Timer()
AddHandler tmr.Elapsed, AddressOf Timer_Elapsed 'Add Handler to New Timer
tmr.SynchronizingObject = frmNew 'Synchronize Timer to newly created form
tmr.Interval = 1000 * multiplier
tmr.Enabled = True
tmr.Start()
End Sub
Public Sub Timer_Elapsed(sender As Object, e As ElapsedEventArgs)
Dim tmr As System.Timers.Timer = DirectCast(sender, System.Timers.Timer)
tmr.Stop() 'Stop Timer
DirectCast(tmr.SynchronizingObject, Form).Close() 'Get Form Timer was synchronized with and close it
tmr.SynchronizingObject = Nothing 'Remove Form reference from timer
RemoveHandler tmr.Elapsed, AddressOf Timer_Elapsed 'Remove Handler from Timer
End Sub
I added some controls to my form at runtime and I need them to call a function when clicked. I don't know how many controls will be added but they all need to run the same function. How would I define the event? Can I define events based on all controls of a given class?
A simple example :
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' creating control
Dim btn1 As Button = New Button()
Dim btn2 As Button = New Button()
btn1.Parent = Me
btn1.Name = "btn1"
btn1.Top = 10
btn1.Text = "Btn1"
btn2.Parent = Me
btn2.Name = "btn2"
btn2.Top = 50
btn2.Text = "Btn2"
'adding handler for click event
AddHandler btn1.Click, AddressOf HandleDynamicButtonClick
AddHandler btn2.Click, AddressOf HandleDynamicButtonClick
End Sub
Private Sub HandleDynamicButtonClick(ByVal sender As Object, ByVal e As EventArgs)
Dim btn As Button = DirectCast(sender, Button)
If btn.Name = "btn1" Then
MessageBox.Show("Btn1 clicked")
ElseIf btn.Name = "btn2" Then
MessageBox.Show("Btn2 Clicked")
End If
End Sub
End Class
Simply:
AddHandler Control.Event, AddressOf MethodExecuting
For example:
AddHandler Button1.Click, AddressOf ClickMethod