Click event for dynamically created labels VB.NET - vb.net

For college, I am creating a gravitational field simulator where two masses are shown along with the magnitude and direction of the gravitational force that they will experience. For the bodies of mass I am using dynamically created ovalshapes, and these ovalshapes each have a label on it showing the mass. These ovalshapes and labels are stored in a listarray. I will need to be able to drag and drop these bodies. For the ovalshapes I am using If OvalShape.ContainsFocus but due to the fact that the labels will be ontop of these ovalshapes I need some sort of way to test whether the mouse is down on the labels. I have tried using an event handler but I get an error "click is not an event of system.collections.listarray" for this code AddHandler labelArray.Click, AddressOf Me.labelArray_ClickSo my questions is, Is there a ways to test whether a label belonging to a listarray has been clicked and which label within the array has been clicked on. Thanks in advance

You need to add the event handler to each label in the array
For Each l As Label In labelArray
AddHandler l.Click, AddressOf myClickHandler
Next
Then in the handler function:
Private Sub myClickHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim clickedLabel As Label = DirectCast(sender, Label) ' Cast the sending object into a Label object
' then do whatever you want with the label such as get it's text and show it in a message box:
MessageBox.Show("Label text Clicked was: " & clickedLabel.Text)
End Sub

Related

How to create any one dynamic controls with a for loop without using location property and the form should grow automatically

How to create multiple button controls with a for loop without getting the controls overlapped and without using location property in Vb.Net.
I have created 'n' number of vb controls dynamically but the created controls are getting overlapped to each other. When I use location property to each controls all the controls are getting displayed as per the location value.
The real problem is, I'm using a panel of width 300 and height 300, under that I need to display the dynamically created controls. I have figured it out which is tedious work and does take a lot of time. My idea is to find the panel width and height then need to check whether the new control which is getting created has ample of space to fit inside the panel.
I need to know few things,
1) How to display the controls dynamically using for loop without getting overlapped over each other and without using location property.
2) I need the container or the panel to grow as per the number of controls which gets created dynamically.
3) Accessing each controls which got displayed using an ID or educate or explain me any better idea.
I created a new WinForms project and added a Button to the top of the form. I added a FlowLayoutPanel under that and made it narrow enough to fit a single Button widthwise. I set the AutoSize property of the FLP to True and the FlowDirection to TopDown. I then added this code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Create the new Button.
Dim btn As New Button
'Add it to the FLP
FlowLayoutPanel1.Controls.Add(btn)
'Get the position of the bottom, left of the Button relative to the form.
Dim pt = PointToClient(btn.PointToScreen(New Point(0, btn.Height)))
'Resize the form to provide clearance below the new Button.
ClientSize = New Size(ClientSize.Width, pt.Y + 10)
End Sub
I then ran the project and started clicking the Button I added. As expected, each click added a new Button to the FLP in a vertical column and the form resized to fit. In order to access such controls in code, you can simply index the Controls collection of the FLP.
try this helps you.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
'Do Something
Else
'Do Something else
End If
Panel1.Controls.Clear()
For i As Integer = 0 To 10 Step 1
Dim b15 As New Button
b15.Text = "Test3"
b15.ID = "a" & i
AddHandler b15.Click, AddressOf updateFunc
Panel1.Controls.Add(b15)
Next
End Sub

Determine an object's runtime X-location

This might be a stupid question, but I'm attempting to move a button to the left by roughly 160 pixels each time the button is pressed. However, I need to know what the x-location is of the object at runtime so I can dynamically add those 160 pixels to it. A real world example of this would be right above (if you happen to be using chrome/firefox-which who isn't?) when the new tab button moves every time a new tab is opened (additionally subtracting those pixels too which is harder because I have to figure out how to handle the tab close event within a QTab control in the QIOS devsuite).
You could do this:
Button1.Location = New Point(Button1.Location.X - 160, Button1.Location.Y)
or this:
Dim pt As Point = Button1.Location
Button1.Location = New Point(pt.X - 160, pt.Y)
or maybe this:
Dim pt As Point = Button1.Location
pt.Offset(-160, 0)
Button1.Location = pt
When you use the WinForm designer, each control on your form is assigned a unique name. When you place a control on the form, the designer automatically assigns a unique name (e.g. Button1), but you can change it to whatever you want. The designer automatically creates a class-level variable (i.e. field) for each control. The name of the variable matches the name of the control. So, for instance, if you call your control Button1, then you can access the X-location of that button via the Button1 variable, like this:
Dim x As Integer = Button1.Left
If you are writing code that is intended to handle events from multiple controls, so you wouldn't know which variable to use, you can use the event handler's sender parameter. Every event handler has a sender As Object parameter which points to the control that is raising the event.
So, for instance, in a the click event, you could do something like this:
Private Sub ClickHandler(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
Dim clickedButton As Button = DirectCast(sender, Button)
Dim x As Integer = clickedButton.Left
End Sub

Finding series item clicked in a chart in VB 2008

I am using VB 2008 with the Microsoft Chart Controls for .NET Framework. Using a pie chart, I would like to find the selected item when the chart is clicked or double clicked.
I am have the click and doubleclick events as shown here, which I have confirmed is being hit, and the the eventarts contains the x,y position of the click.
Private Sub Chart_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs)
Private Sub Chart_Click(ByVal sender As Object, ByVal e As System.EventArgs)
What I would really like to find out is what series item was clicked or doubleclicked (what pie slice).
This is being done in a windows forms application.
How do I get the series item clicked or doubleclicked?
The following gives you the chart element under the Mouse.
Dim HTR as HitTestResult
Dim SelectDataPoint As DataPoint
HTR = Chart1.HitTest(e.x,e.y)
SelectDataPoint = Chart1.Series(0).Points(HTR.PointIndex)
Note that you should probably do some checking to make sure it is a Series that the user clicks on by checking the HTR.ChartElementType. Oh, and this should go in a MouseUp event, since the e that I use are MouseEventArgs.

Access properties of controls on a programatically created user control VB .NET

After taking a few years off from programming, I decided to start learning vb.net. I have created a user control that contains a picture box. I added some custom properties to the picture box that will hold general string data from a database.
My problem is that the user control is programatically created during run time, and during this time a DoubleClick event handler is added for the picture box that is within the user control.
I need to be able to set the custom properties for the picture box during the creation of the user control, so that when the control (picture box) is double clicked I can read these values but am unsure on how to access them.
The picture box is the entire size of the user control, or I would just add the custom properties right to the user control and add the DoubleClick event handler to that. However, double clicking needs to be done on the picture box since it takes up the entire user control, unless anyone has an idea to trigger the DoubleClick event of the user control when the picture box is double clicked.
Here is a bit of code I am using to add the user control to the form programatically -
hb_item = New PictureLoader
With hb_item
.Name = "item_" & i
.Left = itemLeft
.Top = itemTop
.SetImageSizeMode = ImageLayout.Stretch
.SetLoadingImageSizeMode = ImageLayout.Stretch
.Size = New Size(100, 126)
.SetImage = BlobToImage(sql_reader("ThumbImage"))
.Visible = True
.SetHighlight(True)
.SetHighlightColor = Color.GreenYellow
.TextColor = Color.White
.CircleColor = Color.GreenYellow
'--- THIS UPDATES ONE OF THE CUSTOM PROPERTIES FOR THE PICTURE BOX
'--- CONTAINED WITHIN THE USER CONTROL
.SetID = "test"
AddHandler .picMainClick, AddressOf frmHome.HBItem_Click
AddHandler .picMainDoubleClick, AddressOf frmHome.HBItem_DoubleClick
End With
Here is the event handler code I am trying to access the picture box's custom properties from
Public Sub HBItem_DoubleClick(ByVal sender As System.Object, ByVal e As EventArgs) Handles MyBase.DoubleClick
With sender
'--- THIS IS WHERE I WANT TO READ THE DATA IN THE CUSTOM PROPERTIES
'--- OF THE PICTURE BOX... SOMETHING SIMILAR TO THE FOLLOWING -
' Database_ID is one of the custom properties of the sender (picMain
' control on the user control)
MessageBox.Show(.Database_ID)
End With
End Sub
EDIT: Got it all worked out, thanks for everything. All that was needed was casting the sender to the actual picture box like stated, I was just looking way to deeply into things. A simple one line of code is all that was needed in the event handler -
Dim pb As xPictureBox = CType(sender, xPictureBox)
Then all the custom properties could be accessed using pb.property_here.
sender is of type System.Object - you need to cast (convert) sender to the type it actually is (in your case, your custom user control), i.e.:
Dim myControl As MyCustomControl = CType(sender, MyCustomControl)
With myControl
MessageBox.Show(.Database_ID)
End With

Dynamic button click event handler

I've 100 buttons created dynamically in a form. How can I an add event handler to them?
You can use AddHandler to add a handler for any event.
For example, this might be:
AddHandler theButton.Click, AddressOf Me.theButton_Click
Just to round out Reed's answer, you can either get the Button objects from the Form or other container and add the handler, or you could create the Button objects programmatically.
If you get the Button objects from the Form or other container, then you can iterate over the Controls collection of the Form or other container control, such as Panel or FlowLayoutPanel and so on. You can then just add the click handler with
AddHandler ctrl.Click, AddressOf Me.Button_Click (variables as in the code below),
but I prefer to check the type of the Control and cast to a Button so as I'm not adding click handlers for any other controls in the container (such as Labels). Remember that you can add handlers for any event of the Button at this point using AddHandler.
Alternatively, you can create the Button objects programmatically, as in the second block of code below.
Then, of course, you have to write the handler method, as in the third code block below.
Here is an example using Form as the container, but you're probably better off using a Panel or some other container control.
Dim btn as Button = Nothing
For Each ctrl As Control in myForm.Controls
If TypeOf ctrl Is Button Then
btn = DirectCast(ctrl, Button)
AddHandler btn.Click, AddressOf Me.Button_Click ' From answer by Reed.
End If
Next
Alternatively creating the Buttons programmatically, this time adding to a Panel container.
Dim Panel1 As new Panel()
For i As Integer = 1 to 100
btn = New Button()
' Set Button properties or call a method to do so.
Panel1.Controls.Add(btn) ' Add Button to the container.
AddHandler btn.Click, AddressOf Me.Button_Click ' Again from the answer by Reed.
Next
Then your handler will look something like this
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
' Handle your Button clicks here
End Sub
#Debasish Sahu, your answer is an answer to another question, namely: how to know which button (or any other control) was clicked when there is a common handler for a couple of controls? So I'm giving an answer to this question how I usually do it, almost the same as yours, but note that also works without type conversion when it handles the same type of Controls:
Private Sub btn_done_clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim selectedBtn As Button = sender
MsgBox("you have clicked button " & selectedBtn.Name)
End Sub
I needed a common event handler in which I can show from which button it is called without using switch case... and done like this..
Private Sub btn_done_clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
MsgBox.Show("you have clicked button " & CType(CType(sender, _
System.Windows.Forms.Button).Tag, String))
End Sub
Some code for a variation on this problem. Using the above code got me my click events as needed, but I was then stuck trying to work out which button had been clicked.
My scenario is I have a dynamic amount of tab pages. On each tab page are (all dynamically created) 2 charts, 2 DGVs and a pair of radio buttons. Each control has a unique name relative to the tab, but there could be 20 radio buttons with the same name if I had 20 tab pages. The radio buttons switch between which of the 2 graphs and DGVs you get to see. Here is the code for when one of the radio buttons gets checked (There's a nearly identical block that swaps the charts and DGVs back):
Private Sub radioFit_Components_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If sender.name = "radioFit_Components" And sender.visible Then
If sender.checked Then
For Each ctrl As Control In TabControl1.SelectedTab.Controls
Select Case ctrl.Name
Case "embChartSSE_Components"
ctrl.BringToFront()
Case "embChartSSE_Fit_Curve"
ctrl.SendToBack()
Case "dgvFit_Components"
ctrl.BringToFront()
End Select
Next
End If
End If
End Sub
This code will fire for any of the tab pages and swap the charts and DGVs over on any of the tab pages. The sender.visible check is to stop the code firing when the form is being created.