Managing Dynamically created User Controls events - vb.net

I have a User Control that is Dynamically created. It has to raise a Mouse_Move event & Mouse_Down event.
How to manage events for Multiple User Control that are created dynamically. I was considering using a list of user controls to track the controls. But I do not know how to setup the events properly.
Public Class UserControl1
Public Structure Porportions
Dim width_Percent As Double
Dim Height_percent As Double
Dim X_Location_Percent As Double
Dim Y_Location_Percent As Double
End Structure
Dim Pipe As Porportions
Dim guage1 As Porportions
Dim guage2 As Porportions
Public start_pos As Point
Public move_offset As Point
Public Client_Point As Point
Public Pipe_Source As Excel
Public Pipe_Data As DataSet
Public Pipe_Properties As Pipe
Private Pipe_ID As String
' Public Event Pipe_MouseMove(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event Pipe_MouseMove1(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event Pipe_MouseDown1(ByVal sender As Object, ByVal e As System.EventArgs)
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
RaiseEvent Pipe_MouseMove1(sender, e)
End Sub
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
RaiseEvent Pipe_MouseDown1(sender, e)
End Sub
Public Class Form1
Private pipe_cnt As Integer = 0
Private start_position As Point
Private MoveOffset As Point
Private Mouse_Position As Point
Private WithEvents pp As UserControl1
Private Sub Pipe_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles pp.Pipe_MouseMove1
Dim dx As Integer
Dim dy As Integer
Dim m_loc As Point
Dim scrn As Point
m_loc = New Point(e.Location)
Mouse_Position = New Point(e.X, e.Y)
scrn = PointToScreen(Mouse_Position)
Mouse_Position = PointToClient(Mouse_Position)
dx = start_position.X - Mouse_Position.X
dy = start_position.Y - Mouse_Position.Y
MoveOffset = New Point(dx, dy)
If e.Button = MouseButtons.Left Then
Try
pp.Location = New Point(pp.Left + e.X, pp.Top + e.Y)
pp.Location = New Point(pp.Left + e.X, pp.Top + e.Y)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
End Sub
Private Sub Pipe_MouseDown1(ByVal sender As Object, ByVal e As System.EventArgs) Handles pp.Pipe_MouseDown1
start_position = New Point(pp.Location)
End Sub

What I understand that you want to use an same event for multiple user controls. There are many methods to achieve this.
Method 1 (Easiest):
Just put handler events after Handles clause and separate them by commas ,. See example:
Private Sub MouseMove_Event(sender As Object, e As MouseEventArgs) Handles Pipe.MouseMove, PictureBox1.MouseMove
MsgBox("MouseMove")
End Sub
Private Sub Click_Event(sender As Object, e As MouseEventArgs) Handles Pipe.Click, PictureBox1.Click
MsgBox("Click")
End Sub
Private Sub MouseDown_Event(sender As Object, e As MouseEventArgs) Handles Pipe.MouseDown, PictureBox1.MouseDown
MsgBox("MouseDown")
End Sub
Method 2 (burden):
Create and collect all controls in a array of controls and then create events in a foreach loop.
Create Sub that gets array of controls and add handlers using foreach loop.
Private Sub CreateHandlers(Controls() As Control)
For Each control As Control In Controls
Me.Controls.Add(control)
AddHandler control.Click, AddressOf Click_Event
AddHandler control.MouseMove, AddressOf MouseMove_Event
AddHandler control.MouseDown, AddressOf MouseDown_Event
Next
End Sub
Your events
Private Sub Click_Event(sender As Object, e As EventArgs)
'Handle Click events here
End Sub
Private Sub MouseMove_Event(sender As Object, e As EventArgs)
'Handle MouseMove events here
End Sub
Private Sub MouseDown_Event(sender As Object, e As EventArgs)
'Handle MouseDown events here
End Sub
Create controls dynamically and just call CreateHandlers(controls) at end
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim pictureBox1 As PictureBox = New PictureBox _
With {
.Size = New Size(100, 100),
.Location = New Point(0, 0),
.BackColor = Color.Black
}
Dim panel1 As Panel = New Panel _
With {
.Size = New Size(100, 100),
.Location = New Point(100, 0),
.BackColor = Color.Red
}
Dim tableLayoutPanel1 As TableLayoutPanel = New TableLayoutPanel _
With {
.Size = New Size(100, 100),
.Location = New Point(200, 0),
.BackColor = Color.Green
}
Dim controls() As Control = {pictureBox1, panel1, tableLayoutPanel1}
CreateHandlers(controls)
End Sub
End Class

Related

How can i keep adding buttons related to what i wrote when i click the button

Public Class Form3
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim oForm As Form2 = New Form2
Dim btn As Button = New Button With {
.Location = New Point(300, 100),
.Text = TextBox1.Text,
.ForeColor = Color.Black
}
oForm.Controls.Add(btn)
oForm.StartPosition = FormStartPosition.CenterScreen
oForm.Show(Me)
Me.Hide()
End Sub
End Class
I want to keep adding new buttons when the button is clicked but not at the same position i want the buttons to keep adding downwards like this:
[Button1]
[Button2]
[Button3]
You can get your Button1 location and than increase the Y value every time you click on it.
Public Class Form1
Dim Button1Coordinate As Point
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim btn As Button = New Button
Button1Coordinate.Y += 46
With btn
.Location = New Point(Button1Coordinate)
.Text = TextBox1.Text
.ForeColor = Color.Black
End With
Me.Controls.Add(btn)
Me.StartPosition = FormStartPosition.CenterScreen
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Button1Coordinate = Button1.Location
End Sub
End Class
N.B. the default height of a button is 23 pixels

DataGridView right click event and pass-through of parameters to sub

I read a lot of things here in the forum, but I can't find a solution for my problem.
I have a DataGridView with a ContextMenu.
My aim is to call a function from the context menu and pass through parameters e.g. linenumber of selected dgv row.
Here is my code, that contains a ContextMenu, but how I could pass-through some parameters to a function?
Private Sub dataGridView1_MouseClick(ByVal sender As DataGridView, ByVal e As MouseEventArgs) Handles DataGridView1.MouseClick
If e.Button = MouseButtons.Right Then
Dim m As New ContextMenu
m.MenuItems.Add(New MenuItem("Sub1"))
m.MenuItems.Add(New MenuItem("Sub2"))
Dim currentMouseOverRow As Integer = DataGridView1.HitTest(e.X, e.Y).RowIndex
m.Show(DataGridView1, New Point(e.X, e.Y))
End If
End Sub
EDIT
Now I have got a solution that works, but I think it is not the best solution and I can do a lot of improvement.
Maybe it would be possible to code custom events, that can pass through some datas of the gridview. I hope somebody is interested to give some input to improve the following (working) code to look something like professional.
Imports System
Imports System.IO
Public Class Form1
Public gpath As String = "D:\kvt.txt"
Public Sub New()
' This call is required by the designer.
InitializeComponent()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim file = System.IO.File.ReadAllLines("d:\kvt.txt")
Dim dt As New DataTable
dt.Columns.Add("Name")
For Each line As String In file
dt.Rows.Add(line)
Next
DataGridView1.DataSource = dt
DataGridView1.Show()
End Sub
Private Sub dataGridView1_MouseClick(ByVal sender As DataGridView, ByVal e As MouseEventArgs) Handles DataGridView1.MouseClick
Dim cMenu As New ContextMenuStrip
Dim MenuItemClone As New System.Windows.Forms.ToolStripMenuItem
MenuItemClone.Text = "Clone"
cMenu.Items.Add(MenuItemClone)
If e.Button = MouseButtons.Right Then
Dim currentMouseOverRow As Integer = DataGridView1.HitTest(e.X, e.Y).RowIndex
cMenu.Show(DataGridView1, New Point(e.X, e.Y))
AddHandler MenuItemClone.Click, AddressOf CloneRepo
End If
End Sub
Private Sub CloneRepo(ByVal sender As Object, ByVal e As System.EventArgs)
Dim SelectedName As String = DataGridView1("Name", DataGridView1.CurrentCell.RowIndex).FormattedValue
End Sub
End Class
Here's an example of how you can right-click on a cell in a DataGridView and then perform an action relative to that cell when you click a menu item:
Private lastClickedCell As DataGridViewCell
Private Sub DataGridView1_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseClick
If e.ColumnIndex >= 0 AndAlso
e.RowIndex >= 0 Then
lastClickedCell = DataGridView1.Item(e.ColumnIndex, e.RowIndex)
End If
End Sub
Private Sub DataGridView1_MouseClick(sender As Object, e As MouseEventArgs) Handles DataGridView1.MouseClick
If e.Button = MouseButtons.Right AndAlso
DataGridView1.HitTest(e.X, e.Y).Type = DataGridViewHitTestType.Cell Then
'Display the menu when right-clicking on a cell.
ContextMenuStrip1.Show(DataGridView1, e.Location)
End If
End Sub
Private Sub ClearToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClearToolStripMenuItem.Click
'Clear the cell that was right-clicked.
lastClickedCell.Value = Nothing
End Sub
The ContextMenuStrip was created in the designer for this example. I would recommend doing that in your case too, even if you need to choose items dynamically. You can clear the menu and add and/or remove items in the CellMouseClick or MouseClick event handlers of the grid, or the Opening event handler of the menu.
Private Sub DataGridView1_MouseClick(sender As Object, e As MouseEventArgs) Handles DataGridView1.MouseClick
Dim col As New DataGridTextBoxColumn
If e.Button = MouseButtons.Right Then
Dim m As New ContextMenuStrip
col.TextBox.ContextMenuStrip = m
Dim tsp As New ToolStripMenuItem("Sub1", Nothing, New EventHandler(AddressOf TestMessage))
Dim tsp1 As New ToolStripMenuItem("Sub2", Nothing, New EventHandler(AddressOf TestMessage))
m.Name = "Menulist"
m.Items.Add(tsp)
m.Items.Add(tsp1)
Dim currentMouseOverRow As Integer = DataGridView1.HitTest(e.X, e.Y).RowIndex
m.Show(DataGridView1, New Point(e.X, e.Y))
End If
End Sub
Private Sub TestMessage()
MessageBox.Show("Clicked")
End Sub
try this and use 'Tag':
Dim currentMouseOverRow As Integer
Structure MyStructure
Public x As Integer
Public y As Integer
End Structure
Private Sub DataGridView1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseClick
Dim Mystruct As MyStructure
If e.Button = Windows.Forms.MouseButtons.Right Then
Dim m As New System.Windows.Forms.ContextMenuStrip
Dim MymenuToolStripMenuItem1 As New System.Windows.Forms.ToolStripMenuItem
MymenuToolStripMenuItem1.Text = "menu1"
AddHandler MymenuToolStripMenuItem1.Click, AddressOf MymenuToolStripMenuItem1_Click
m.Items.Add(MymenuToolStripMenuItem1)
Dim MymenuToolStripMenuItem2 As New System.Windows.Forms.ToolStripMenuItem
MymenuToolStripMenuItem2.Text = "menu2"
AddHandler MymenuToolStripMenuItem2.Click, AddressOf MymenuToolStripMenuItem2_Click
m.Items.Add(MymenuToolStripMenuItem2)
Mystruct.x = e.X
Mystruct.x = e.X
MymenuToolStripMenuItem2.Tag = Mystruct
currentMouseOverRow = DataGridView1.HitTest(e.X, e.Y).RowIndex
m.Show(DataGridView1, New Point(e.X, e.Y))
End If
End Sub
Private Sub MymenuToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
MessageBox.Show("click Menu1:" & currentMouseOverRow)
End Sub
Private Sub MymenuToolStripMenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim Mystruct As MyStructure
Mystruct = CType(CType(sender, System.Windows.Forms.ToolStripMenuItem).Tag, MyStructure)
MessageBox.Show("click Menu2:" & currentMouseOverRow & " x:" & Mystruct.x & " y:" & Mystruct.y)
End Sub

How to move picture boxes in a panel using vb.net

I'm trying to move picture boxes in a panel.
This is my Code:
Private dragging As Boolean
Private beginX, beginY As Integer
Private Sub Control_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
dragging = True
beginX = CType(sender, PictureBox).Location.X
beginY = CType(sender, PictureBox).Location.Y
End Sub
Private Sub Control_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim cntrl As Control = CType(sender, Control)
If dragging = True Then
cntrl.Location = New Point(cntrl.Location.X + e.X - beginX, cntrl.Location.Y + e.Y - beginY)
'Me.Refresh()
End If
End Sub
Private Sub Control_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
dragging = False
End Sub
I can't figure out why this don't work.
The subroutines you have are missing their handlers (ie the handles statement) at the end.
ex:
Private Sub Control_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) HANDLES controlName.MouseUp
dragging = False
End Sub
Try this:
Dim cmd As Boolean = False
Dim sp As Point
Private Sub Form1_Load() Handles MyBase.Load
For Each Control As Picturebox In Me.Controls.OfType(Of Picturebox)
AddHandler Control.MouseDown, Sub(sender As Object, e As MouseEventArgs)
cmd = True
sp = e.Location
End Sub
AddHandler Control.MouseMove, Sub(sender As Object, e As MouseEventArgs)
If cmd Then
Control.Location = Control.Location - sp + e.Location
End If
End Sub
AddHandler Control.MouseUp, Sub(sender As Object, e As MouseEventArgs)
cmd = False
End Sub
Next
End Sub

Can't draw rectangle around textbox in Groupbox, using Visual Basic 2010.-

I have two textbox controls in a vb form.- I can draw rectangles about the two textbox if they aren't in a groupbox.- Only when the textbox got the focus the rectangle is drawed.- The code works, but somehow, when i put the textbox in a groupbox the rectangles aren't drawed.-
the rectangle only is drawed when textbox is focused
This is the code that i have been using.-
Public Class Form1
Dim curControl As TextBox
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
If Not curControl Is Nothing Then
If curControl.Name = "TextBox1" Then
Dim g As Graphics = e.Graphics
Dim pen As New Pen(Color.Lime, 2.0)
g.DrawRectangle(pen, New Rectangle(TextBox1.Location, TextBox1.Size))
pen.Dispose()
End If
End If
If Not curControl Is Nothing Then
If curControl.Name = "TextBox2" Then
Dim g As Graphics = e.Graphics
Dim pen As New Pen(Color.Red, 2.0)
g.DrawRectangle(pen, New Rectangle(TextBox2.Location, TextBox2.Size))
pen.Dispose()
End If
End If
End Sub
Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles TextBox1.Enter, TextBox2.Enter
curControl = DirectCast(sender, TextBox)
Me.Invalidate()
End Sub
Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As EventArgs) Handles TextBox1.Leave, TextBox2.Leave
curControl = Nothing
Me.Invalidate()
End Sub

Is it possible to print or save the picturebox with other picture box within it

I am a vb.net beginner. I got a project that I need to do function that enabled user to add new picture(which is a new picturebox) and move it in a picture box. I have made these two happened but I don`t know how to make the picturebox(that allow new picturebox move inside) save as bitmap/jpg into database. Is that possible to do that.If yes, how?
Public Class Form1
Private btn As Button ' this is a reference object
Private pic As PictureBox
Private ptX, ptY As Integer
Private drag As Boolean
Private Sub nodepic_MouseDown(ByVal senderPic As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = MouseButtons.Left Then
drag = True
pic = CType(senderPic, PictureBox)
ptX = e.X : ptY = e.Y
End If
If pic.Focused Then
clearButton.Enabled = True
End If
End Sub
Private Sub nodepic_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If drag Then
If pic.Location.X >= 1 AndAlso pic.Location.Y >= 1 AndAlso
(pic.Location.X + pic.Width) <= panelPictureBox.Width - 5 AndAlso
(pic.Location.Y + pic.Height) <= panelPictureBox.Height - 5 Then
pic.Location = New Point(pic.Location.X + e.X - ptX, pic.Location.Y + e.Y - ptY)
Me.Refresh()
Else
drag = False
pic.Location = New Point(pic.Location.X + e.X - ptX, pic.Location.Y + e.Y - ptY)
End If
End If
End Sub
Private Sub node_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
drag = False
End Sub
Private Sub deleteButton(senderPic As Object, e As EventArgs)
Dim delete As DialogResult
delete = MessageBox.Show("Are you sure to delete this icon?", "Delete Icon", MessageBoxButtons.YesNo)
If delete = Windows.Forms.DialogResult.Yes Then
senderPic.Dispose()
locationLabel.Text = String.Empty
End If
End Sub
Private Sub locationButton(senderPic As Object, e As System.Windows.Forms.MouseEventArgs)
pic.Location = New Point(pic.Location.X + e.X - ptX, pic.Location.Y + e.Y - ptY)
locationLabel.Text = pic.Location.ToString()
End Sub
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
Dim picBox As New PictureBox
If e.Node.Name.Equals("red") Then
picBox.Image = ImageList1.Images(0)
End If
If e.Node.Name.Equals("orange") Then
picBox.Image = ImageList1.Images(1)
End If
picBox.Location = New Point(10, 10)
panelPictureBox.Controls.Add(picBox)
action(picBox)
End Sub
Private Sub action(sender As PictureBox)
AddHandler sender.MouseDown, AddressOf nodepic_MouseDown
AddHandler sender.MouseMove, AddressOf nodepic_MouseMove
AddHandler sender.MouseUp, AddressOf node_MouseUp
AddHandler sender.MouseDoubleClick, AddressOf deleteButton
AddHandler sender.MouseClick, AddressOf locationButton
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
panelPictureBox.Enabled = True
panelPictureBox.BackColor = Color.White
End Sub
Private Sub clearButton_Click(senderPic As Object, e As EventArgs) Handles clearButton.Click
pic.Dispose()
End Sub**strong text**
End Class
You can save the PictureBox, along with its "child" PictureBoxes, to a Bitmap using code like this:
Dim bmp As New Bitmap(panelPictureBox.Width, panelPictureBox.Height)
panelPictureBox.DrawToBitmap(bmp, panelPictureBox.ClientRectangle)
Next you save it to memory by writing it out to a MemoryStream. Note that you can specify the format in the second parameter:
Dim ms As New System.IO.MemoryStream()
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
Finally, you can obtain a byte array from the resulting MemoryStream:
Dim bytes() As Byte = ms.ToArray
' ... save "bytes" to your database ...
if you need to print the image inside the picturebox then you should insert printdialog ,printdocument in side the design of the form then copy the code below
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
PrintDialog1 = New PrintDialog
PrintDialog1.Document = PrintDocument1 'pbxLogo.Image
Dim r As DialogResult = PrintDialog1.ShowDialog
If r = DialogResult.OK Then
PrintDocument1.Print()
End If
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
e.Graphics.DrawImage(PictureBox1.Image, 0, 0)
End Sub