Fire Panel's Click event - vb.net

I was looking for how to automatically fire a Click event for a Panel. I found code to do this for a Button and it is not the same.
My problem is: I am making an auto gallery generator and I want fire the event when you click the parent block which contains the id for the user. The problem is when I click the event the image and the label are before block, then if I click image or label I want that block is clicked.
Here is my code:
Public Class users
Private Sub users_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' COMPROVE CONNECTION
Try
' ESTABLISH CONNECTION TO SERVER
conn = New DataBase(DbServer, DbName, DbUser, Password)
' PICK UP DATA FROM USERS
Dim DataTable As New DataTable
DataTable = conn.ConsultSql("SELECT `id_user`,`full_name`,`img` FROM `user` WHERE `user_type` = 1")
' PRINT PHARMACIST
Dim b As Integer = 0
While b < DataTable.Rows.Count
Dim RowData As DataRow = DataTable.Rows(b)
PrintUsers(RowData)
b += 1
End While
Catch ex As Exception
MessageBox.Show("Ocurrió el siguiente error: " & ex.Message, "Error al loguearse", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Public Sub PrintUsers(ByVal RowData As DataRow)
Dim iNumber As String
Console.WriteLine(RowData("full_name"))
iNumber = RowData("full_name")
' GENERATE ID
Dim oPaneldId As New Panel
oPaneldId.Name = RowData("id_user")
' GENERATE TEXT NAME
Dim oTextField As New Label
oTextField.Name = "name" & iNumber
oTextField.Text = iNumber
' GENEREATE PHOTO
Dim oPictureBox As New PictureBox
oPictureBox.Name = "img" & iNumber
Dim MyWebClient As New System.Net.WebClient
'BYTE ARRAY HOLDS THE DATA
Dim ImageInBytes() As Byte = MyWebClient.DownloadData(RowData("img"))
'CREATE A MEMORY STREAM USING THE BYTES
Dim ImageStream As New IO.MemoryStream(ImageInBytes)
'CREATE A BITMAP FROM THE MEMORY STREAM
oPictureBox.Image = New System.Drawing.Bitmap(ImageStream)
oPictureBox.Size = New Size(100, 130)
' ADDING TO THE BODY
oPaneldId.Controls.Add(oTextField)
oPaneldId.Controls.Add(oPictureBox)
AddHandler oPaneldId.Click, AddressOf Me.SelectUser
AddHandler oPictureBox.Click, AddressOf Me.ClickFather
AddHandler oTextField.Click, AddressOf Me.ClickFather
body.Controls.Add(oPaneldId)
End Sub
Public Sub SelectUser()
Console.WriteLine("Funciona")
End Sub
Public Sub ClickFather(sender As Object, e As EventArgs)
Console.WriteLine(sender.GetType.Name)
Console.WriteLine(sender.parent.Name)
sender.parent.click
End Sub
End Class

Add the click event handlers for the other controls in the panel to the same event handler you use for the panel`s click event. So your code would change to
AddHandler oPaneldId.Click, AddressOf Me.SelectUser
AddHandler oPictureBox.Click, AddressOf Me.SelectUser
AddHandler oTextField.Click, AddressOf Me.SelectUser

Related

Windows Forms Modal Form Closes instantly when Base form is not Active

I have a Winforms Application which should notify the user when something in a database changes. For that i use Sql-Dependencys, which works fine.
When the Dependency fires i am able to show a form with some Buttons so the user can decide what he wants to do.
After one Button i want to show a Dialog, but the first Dialog always gets closed instantly.
The only fix i found until now is restoring the base form and activating it, but that is not the solution i am looking for.
For the code i am doing the Following:
This Method gets called when something changes in the Database
Private Sub NutzerBenachrichtigen(Aenderung As Aenderung)
If InvokeRequired Then
Me.BeginInvoke(New MethodInvoker(Sub()
ErzeugeBenachrichtigung(Aenderung)
End Sub))
Else
ErzeugeBenachrichtigung(Aenderung)
End If
End Sub
This Method Displays the first form (HeadsUp is taken from this here :https://github.com/glm9637/MaterialWinforms/blob/master/MaterialWinforms/Controls/HeadsUp.cs)
Private Sub ErzeugeBenachrichtigung(ByVal Aenderung As Aenderung)
If Aenderung.istAktuellerBenutzer Then
Dim objHeadsUp As New HeadsUp()
objHeadsUp.Titel = "Neue Aenderung"
If Aenderung.EventTyp.ToLower = "alter" Then
objHeadsUp.Text = String.Format("Du hast etwas an {0} {1} {2} geändert. {3}Willst du etwas dazu schreiben?", _
If(Aenderung.BetroffenesObjekt.EntitaetTyp.Name = New EntitaetTyp.Trigger().Name, "dem", "der"), _
Aenderung.BetroffenesObjekt.EntitaetTyp.Name, Aenderung.BetroffenesObjekt.Name, vbNewLine)
Else
objHeadsUp.Text = String.Format("Du hast {0} {1} {2} erstellt. {3}Willst du etwas dazu schreiben?", _
If(Aenderung.BetroffenesObjekt.EntitaetTyp.Name = New EntitaetTyp.Trigger().Name, "den", "die"), _
Aenderung.BetroffenesObjekt.EntitaetTyp.Name, Aenderung.BetroffenesObjekt.Name, vbNewLine)
End If
objHeadsUp.Tag = Aenderung.BetroffenesObjekt
Dim objButtonSchliessen = New MaterialFlatButton
objButtonSchliessen.Tag = objHeadsUp
objButtonSchliessen.Text = "Schliessen"
AddHandler objButtonSchliessen.Click, AddressOf SchliesseHeadsUp
objHeadsUp.Buttons.Add(objButtonSchliessen)
Dim objButtonHistorie = New MaterialFlatButton
objButtonHistorie.Tag = objHeadsUp
objButtonHistorie.Text = "Historieneintrag"
AddHandler objButtonHistorie.Click, AddressOf HistorienEintragHinzufuegen
objHeadsUp.Buttons.Add(objButtonSchliessen)
Dim objButtonDokumentation = New MaterialFlatButton
objButtonDokumentation.Tag = objHeadsUp
objButtonDokumentation.Text = "Dokumentation"
AddHandler objButtonDokumentation.Click, AddressOf DokumentationBearbeiten
objHeadsUp.Buttons.Add(objButtonSchliessen)
objHeadsUp.Buttons.Add(objButtonHistorie)
objHeadsUp.Buttons.Add(objButtonDokumentation)
objHeadsUp.Show()
ElseIf Aenderung.EventTyp = "CLOSE_MESSAGE" Then
Dim objHeadsUp As New HeadsUp()
objHeadsUp.Titel = "Achtung"
objHeadsUp.Text = "Die Anwendung muss für eine Aktualisierung geschlossen werden."
Dim objButtonSchliessen = New MaterialFlatButton
objButtonSchliessen.Tag = objHeadsUp
objButtonSchliessen.Text = "Anwendung Schliessen"
AddHandler objButtonSchliessen.Click, AddressOf AnwendungSchliessen
objHeadsUp.Buttons.Add(objButtonSchliessen)
objHeadsUp.Show()
Else
If mtc_UebersichtTabControl.SelectedTab.Text = "Aenderung" Then
mAenderungenUebersicht.Aktualisieren()
End If
End If
End Sub
Finally when the "Historieneintrag" Button is pressed this Method gets called:
Private Sub HistorienEintragHinzufuegen(sender As Object, e As EventArgs)
Dim blnNachDialogVerstecken As Boolean = False
Dim objFlatButton As MaterialFlatButton = sender
Dim HeadsUp As HeadsUp = objFlatButton.Tag
Dim Objekt As Entitaet = HeadsUp.Tag
Dim objOldLocation As System.Drawing.Point = Location
HeadsUp.Close()
Dim objDialogContent As New HistorienEintrag()
''Hacky: Ansonsten wird der Dialog sofort geschlossen
If WindowState = FormWindowState.Minimized Or Not Visible Then
Location = New System.Drawing.Point(-Width * 2, -Height - 2)
Me.Show()
blnNachDialogVerstecken = True
End If
Activate()
If MaterialDialog.Show("Neuer Historien Eintrag", objDialogContent, MaterialWinforms.Controls.MaterialDialog.Buttons.OKCancel, MaterialDialog.Icon.Info) = DialogResult.OK Then
Objekt.HistorieSpeichern(objDialogContent.Ergebniss)
End If
If blnNachDialogVerstecken Then
Me.Hide()
Location = objOldLocation
End If
End Sub
In here the first modal Form, so a MessageBox.Show("") or any other form closes Instantly if i don't do the show and activate part.
What am i doing wrong here?
Project > (Project) Properties > Application > Shutdown mode
change from when startup form closes to when last form closes

How do I add then select the dynamic control I just added

I've got an application in VB.net which adds a picturebox to the selected mouse position within another picturebox control. I need to create a click event to select that new picturebox so I can drag it and drop it to a new location in the event that the first one was wrong or use a keypress event, those events I will code later, but I can not figure out how to select ANY of the dynamic controls.
In vb6 there was a way to select an index of the control, but there is no such animal in VB.net.
I've tried control groups, but for some reason I'm not getting results from them.
Here is the code I have so far
Private Sub PictureBox1_Click(sender As System.Object,
e As System.EventArgs) Handles PictureBox1.Click
Dim pb As New PictureBox
pb.BackColor = Color.Blue
Me.PictureBox1.Controls.Add(pb)
pb.Size = New Size(64, 110)
pb.Location = New Point(Cursor.Position.X - 64, Cursor.Position.Y - 110)
pb.Visible = True
End Sub
What in the name of all good things am I doing wrong here?
You need to write a generic event handler before time, using the sender parameter to refer to the object that raised the event.
Private Sub PictureBoxes_Click(sender As Object, e As EventArgs)
Dim pb = DirectCast(sender, PictureBox)
'Use pb here.
End Sub
When you create your control at run time, use an AddHandler statement to attach the method to the event.
Dim pb As New PictureBox
AddHandler pb.Click, AddressOf PictureBoxes_Click
That said, if you want to implement drag-n-drop then it's not the Click event you should be handling.
This little bit of code took some time, but I was able to do what I set out to so far...
This is before the Sub Main event
Public Class dynamicPB 'create a picturebox element which
'can be called anytime
Inherits PictureBox 'sets the type of control to a
'picturebox
Public Sub New() 'sets the function of the new box to
'default values
MyBase.BackColor = Color.AliceBlue
MyBase.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
MyBase.Height = 50
MyBase.Width = 26
End Sub
End Class
in the actual main class
Private Sub <control_event> (blah...) Blah...
Dim intPosAdj_X As Integer = 13 'get an offset for the cursor
Dim intPosAdj_Y As Integer = 25
Dim newPictureBox As New dynamicPB 'sets the click of the mouse into a
'mode of drawing a new PB
With newPictureBox 'clean use of the code
AddHandler newPictureBox.Click, _
AddressOf PictureBox_Click 'establishes events for the mouse
'activity on the objects
AddHandler newPictureBox.MouseEnter, _
AddressOf PictureBox_MouseEnter
AddHandler newPictureBox.MouseLeave, _
AddressOf PictureBox_MouseLeave
pbName += 1 'gives a unique name to the
'picturebox in an "array" style
.Location = New System.Drawing.Point _
(xPos - intPosAdj_X, yPos - intPosAdj_Y) 'establish where the box goes
'and center the object on the
'mouse pointer
.Visible = True 'ensures that the box is visible
.Name = pbName 'names the new control
End With
Controls.Add(newPictureBox) 'add control to form
End Sub
Private Sub PictureBox_Click(sender As System.Object, e As System.EventArgs)
Dim dblMouseClick As Double = CType(DirectCast _
(e, System.Windows.Forms.MouseEventArgs).Button, MouseButtons) _
'make it simple to manipulate
'the event by putting the long
'code into a variable
If dblMouseClick = MouseButtons.Left Then
MsgBox("Left CLick")
ElseIf dblMouseClick = MouseButtons.Right Then
MsgBox("right click")
Else
MsgBox("Center")
End If
This actually resolves the issue of adding and being able to select the object
Thanks for all of the suggestions and help

How to add event handler to a dynamically created control in VB.NET?

I have searched and seen countless samples here in this forum and in other sites but I'm still stuck with this problem;
I want to add a Click Handler for dynamically created PictureBox-es and pas an argument on it so I know which one of picture boxes was clicked).
Here is my current code:
Public Class frmMbarimAbonimi
Private Sub frmMbarimAbonimi_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'FitnessdbDataSet.clients' table. You can move, or remove it, as needed.
'Me.ClientsTableAdapter.Fill(Me.FitnessdbDataSet.clients)
'===============
Dim dt As DataTable = PaPaguar()
Dim i As Integer = 0
Dim gr(dt.Rows.Count) As GroupBox
Dim pp(dt.Rows.Count) As PictureBox
Dim lb(dt.Rows.Count) As Label
For Each row As DataRow In dt.Rows
gr(i) = New GroupBox
gr(i).Width = 200
gr(i).Height = 180
pp(i) = New PictureBox
pp(i).SizeMode = PictureBoxSizeMode.StretchImage
lb(i) = New Label
'-------------------------
Try
Using str As Stream = File.OpenRead("C:\Fotot\" + dt.Rows(i).Item("Foto"))
pp(i).Image = Image.FromStream(str)
End Using
lb(i).Text = dt.Rows(i).Item("Emer")
Catch ex As Exception
MsgBox("Fotoja nuk mund te ngarkohet, ju lutem realizoheni nje foto tjeter!!!")
End Try
'-------------------------
pp(i).Visible = True
pp(i).Width = 200
pp(i).Height = 150
AddHandler pp(i).Click, AddressOf testini
gr(i).Controls.Add(pp(i))
lb(i).Visible = True
lb(i).Width = 200
lb(i).Height = 30
lb(i).Left = pp(i).Left
lb(i).Top = pp(i).Top + 150
lb(i).BackColor = Color.WhiteSmoke
lb(i).BringToFront()
gr(i).Controls.Add(lb(i))
flpanel.Controls.Add(gr(i))
i = i + 1
Next row
End Sub
End Class
So I was trying to use AddHandler pp(i).Click, AddressOf testini but obviously this does not allow me to call "testini" with a parameter to identify which picture box was clicked.
Can someone point me in the right direction or give some advice? Greatly appreciated.
You need to add something to your created PictureBox to identify them in the event handler because you can't change the signature of the click event handler adding a 'parameter'
For example, you could set the Name property
pp(i) = New GroupBox
pp(i).Name = "PictureBox" + i.ToString
then in the event handler you could recognize your picture box casting the sender object to a picturebox and grabbing the Name property.
Remember, sender is always the control that triggers the event. In your case is always one of your dinamically created PictureBoxes
Private Sub testini(sender As Object, e As System.EventArgs)
Dim pb As PictureBox = DirectCast(sender, PictureBox)
Dim pbIdentity As String = pb.Name
.....
End Sub

Passing arguments from a dynamic control to AddHandler in VB.NET

I'm trying to figure out how to pass information from one form to another using an AddHandler that I create in a dynamic control.
I have a loop something like
Dim I As Integer
For I = 0 To 10
Dim gbNew As New GroupBox()
Dim pbNew As New PictureBox()
Dim llbNew As New Label()
Dim tlbNew As New Label()
Dim olbNew As New Label()
Dim slbNew As New Label()
Dim wlbNew As New Label()
UserName = dt.Rows(I)("UserName").ToString()
Status = dt.Rows(I)("LastJobType").ToString()
JobType = dt.Rows(I)("LastJobType").ToString()
LLocation = dt.Rows(I)("LastLocation").ToString()
TimeIn = dt.Rows(I)("LogInTime")
TimeOut = dt.Rows(I)("LogOutTime")
FlowLayoutPanel1.Controls.Add(gbNew)
gbNew.Controls.Add(llbNew)
llbNew.Visible = True
llbNew.Text = LLocation
llbNew.Font = New Font(llbNew.Font.FontFamily, 6.5)
llbNew.Location = New System.Drawing.Point(3, 25)
llbNew.BorderStyle = BorderStyle.None
llbNew.TextAlign = ContentAlignment.MiddleLeft
llbNew.Size = New Size(80, 15)
gbNew.Size = New System.Drawing.Size(270, 80)
'gbNew.BackColor = System.Drawing.Color.Silver
gbNew.Visible = True
gbNew.Text = UserName & " " & I + 1
AddHandler gbNew.Click, AddressOf ShowForm
Next
The eventhandler fires off a sub ShowForm:
Private Sub ShowForm()
Details.Show()
End Sub
This in turn pops up a form, but I can't figure out how to pass a few needed bits of information from the dynamic generated control to a static control outside the loop.
I was using a static control in a form:
label1.text = "something"
And I opened the new form, and I could read that into the new form using something like
dim info as string = form1.label.text. But since it is dynamic, I don't have a label1.text. Instead, I have a llbNew.Text which seems to be something I can't call from form2 :(
How can I pass information from form1's dynamic control to form2?
Please keep this to VB.NET, not C#, as I barely understand VB.NET let alone trying to brain convert from C# which I have zero knowledge of.
Here's a direction you could take. I hope it is clear:
For I = 0 To 10
(...)
gbNew.Text = UserName & " " & I + 1
gbNew.Tag = dt.Rows(I) ' Any information that you need here
AddHandler gbNew.Click, AddressOf ShowForm '(No changes here)
Next
' Use the appropriate Event Handler signature # the handler Sub
Private Sub ShowForm(sender as Object, e as EventArgs)
Dim groupBoxClicked as GroupBox = TryCast(sender, GroupBox)
If groupBoxClicked IsNot Nothing
Dim detailsForm as New Details()
detailsForm.ParentInformation = groupBoxClicked.Tag
detailsForm.ShowDialog()
End If
End Sub
(...)
Public Class Details ' Your Details Form
Public Property ParentInformation as DataRow
End Class

ContextMenuStrip event handler at runtime

I create Context menu at runtime depends of text in selected cell of datagridview.
Like this:
With ContextMenuStrip1
.Items.Clear()
Dim Str As String = DataGridView1.Item(1, DataGridView1.CurrentRow.Index).Value
Dim strArr() As String = Str.Split(" ")
For count As Integer = 0 To strArr.Length - 1
If strArr(count).Length > 1 Then
.Items.Add(strArr(count))
End If
Next
.Items.Add("-")
.Items.Add("Common operation ...")
.Items.Add("Second common operation ...")
AddHandler .Click, AddressOf cMenu_Click
.Show(New Point(Cursor.Position.X, Cursor.Position.Y))
End With
etc...
Then I add event handler like this:
Private Sub cMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim mytext As String
mytext = (CType(sender, ContextMenuStrip).Text)
Debug.Print(mytext)
'after all...
RemoveHandler ContextMenuStrip1.Click, AddressOf cMenu_Click
End Sub
And as vbnet beginner with this code I can't get text of fired menu item in event handler.
So please help to get it.
Each menu item needs the handler.
Try it this way (updated with adding a shortcut key):
For count As Integer = 0 To strArr.Length - 1
If strArr(count).Length > 1 Then
Dim newMenu As New ToolStripMenuItem(strArr(count), _
Nothing, AddressOf cMenu_Click)
newMenu.ShortcutKeys = Keys.Control Or Keys.C
.Items.Add(newMenu)
End If
Next
Your click method should be changed to handle a ToolStripMenuItem instead:
Private Sub cMenu_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim mytext As String
mytext = DirectCast(sender, ToolStripMenuItem).Text
Debug.Print(mytext)
End Sub
Add a handler (pointing to the same method) for the Click Event of all of the child Items of your ContextMenuStrip. Then in your method cast it as a ToolStripMenuItem or MenuItem class (whatever you're using) to find the text of the clicked item.