Drag data from DG and other controls to another DG in vb.net - vb.net

I have form in VB.Net 2010:
I want to click-drag multi rows in dgRegister and Date, Course ID to drop in dgCourseStudent with column Date, Register ID, Register Name and Course ID.
How to code this in vb.net language?

First of all put the AllowDrop property of dgCourseStudent to True (it will accept the dragging events). I've presumed you're using DataSet or DataTable, here my example:
Dim downHitInfo As DataGridView.HitTestInfo = Nothing 'Used to keep trace of dragging info
''MouseDown used to know is a DragDrop event is required
Private Sub dgRegister_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgRegister.MouseDown
Dim view As DataGridView = CType(sender, DataGridView)
Dim hitInfo As DataGridView.HitTestInfo = view.HitTest(e.X, e.Y)
If Not Control.ModifierKeys = Keys.None Then
Exit Sub
End If
If e.Button = MouseButtons.Left And hitInfo.RowIndex >= 0 Then
downHitInfo = hitInfo
End If
End Sub
''MouseMove used to know what DataRow is being dragged.
Private Sub dgRegister_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgRegister.MouseMove
Dim view As DataGridView = CType(sender, DataGridView)
If e.Button = MouseButtons.Left And Not downHitInfo Is Nothing Then
Dim dragSize As Size = SystemInformation.DragSize
Dim DragRect As Rectangle = New Rectangle(New Point(Convert.ToInt32(downHitInfo.ColumnX - dragSize.Width / 2), _
Convert.ToInt32(downHitInfo.RowY - dragSize.Height / 2)), dragSize)
If Not DragRect.Contains(New Point(e.X, e.Y)) Then
'Extract the DataRow
Dim gridRowView As DataGridViewRow = DirectCast(view.Rows(downHitInfo.RowIndex), DataGridViewRow)
Dim rowView As DataRowView = DirectCast(gridRowView.DataBoundItem, DataRowView)
'Raise the DragDrop with the extracted DataRow
view.DoDragDrop(rowView.Row, DragDropEffects.Move)
downHitInfo = Nothing
End If
End If
End Sub
'' For mouse cursor
Private Sub dgCourseStudent_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles dgCourseStudent.DragOver
e.Effect = DragDropEffects.Move
End Sub
''The core of draggin procedure
Private Sub dgCourseStudent_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles dgCourseStudent.DragDrop
'Retreive the dragged DataRow
Dim draggedRow As DataRow = CType(e.Data.GetData(GetType(DataRow)), DataRow)
''
'' Put your code here to insert the dragged row into dgCourseStudent grid
End Sub

Related

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

Selecting row that was dragged and dropped in datagridview

I created a datagridview with some sample data. When I drag a row in the datagridview to another position this works fine. The only thing I can't get working after hours of attempts is to get the row highlighted that was dragged.
In my code the row gets highlighted where the row was originally.
Below some screenshots:
As you can see I moved row 8 to row 14 but row instead of highlighting row 14 it stays on row 8.
My code stripped:
Private Sub DataGridViewForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadDataGridView1()
End Sub
Public Sub LoadDataGridView1()
' Fill datasource
End Sub
Private Sub Dgv_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DatagridView1.DragDrop
' Code to move row up or down
End Sub
Private Sub Dgv_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DatagridView1.DragEnter
e.Effect = DragDropEffects.Copy
End Sub
Private Sub DataGridView_CellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DatagridView1.CellMouseDown
Dim dname As DataGridView = sender
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim view As DataGridViewRow = DirectCast(dname.Rows(e.RowIndex), DataGridViewRow)
If view IsNot Nothing Then
dname.DoDragDrop(view, DragDropEffects.Copy)
End If
LoadDataGridView1()
End If
End Sub
I fixed it as follows for anyone interested:
In the CellMouseDown i set the colors:
Private Sub Dgv_CellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DgvPersonen.CellMouseDown
Dim dname As DataGridView = sender
dname.DefaultCellStyle.BackColor = Color.White
dname.DefaultCellStyle.SelectionBackColor = Color.Tomato
dname.AlternatingRowsDefaultCellStyle.BackColor = MyCustomColor
dname.AlternatingRowsDefaultCellStyle.SelectionBackColor = Color.Tomato
When it was a left mousebutton click on a row I select the row and save the color it was:
dname.CurrentCell = dname(e.ColumnIndex, e.RowIndex)
OriginalColor = dname.Rows(OriginalRow).DefaultCellStyle.BackColor
dname.Rows(OriginalRow).DefaultCellStyle.BackColor = OriginalColor
dname.Rows(LastRow).DefaultCellStyle.BackColor = OriginalColor
Dim view As DataGridViewRow = DirectCast(dname.Rows(e.RowIndex), DataGridViewRow)
If view IsNot Nothing Then
dname.DoDragDrop(view, DragDropEffects.Copy)
End If
OriginalRow and LastRow only get set when drag&drop rows as follows:
Private Sub Dgv_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DgvPersonen.DragDrop
Dim dname As DataGridView = sender
dname.DefaultCellStyle.BackColor = Color.White
dname.DefaultCellStyle.SelectionBackColor = Color.Tomato
dname.AlternatingRowsDefaultCellStyle.BackColor = MyCustomColor
dname.AlternatingRowsDefaultCellStyle.SelectionBackColor = Color.Tomato
Dim newRow As DataGridViewRow = dname.Rows(dname.HitTest(p.X, p.Y).RowIndex)
If newRow.Index >= 0 And newRow.Index < dname.Rows.Count Then
' Get the dropped row info
Dim oldRow As DataGridViewRow = DirectCast(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow)
' If the two rows aren't the same it inserts dropped row
If newRow.Index <> oldRow.Index Then
OriginalRow = oldRow.Index
LastRow = newRow.Index
OriginalColor = dname.Rows(OriginalRow).DefaultCellStyle.BackColor
FillDataGridViewsOnValue()
dname.Rows(OriginalRow).DefaultCellStyle.BackColor = OriginalColor
dname.Rows(LastRow).DefaultCellStyle.BackColor = Color.Tomato
dname.Rows(LastRow).Selected = True
dname.DefaultCellStyle.BackColor = Color.White
dname.DefaultCellStyle.SelectionBackColor = Color.White
dname.AlternatingRowsDefaultCellStyle.BackColor = MyCustomColor
dname.AlternatingRowsDefaultCellStyle.SelectionBackColor = MyCustomColor
It was a lot of trial and error but it works now exactly like a want it to work.

How to Drag And Drop selected rows between DataGridViews

I need to implement drag and drop of the selected rows from one grid to the other:
my code:
datagridview1
Private Sub datagridview1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles datagridview1.MouseDown
Dim info As DataGridView.HitTestInfo = Me.datagridview1.HitTest(e.X, e.Y)
If info.Type = DataGridViewHitTestType.Cell And e.Button = Windows.Forms.MouseButtons.Left Then
Me.datagridview1.DoDragDrop(datagridview1.SelectedRows.Cast(Of DataGridViewRow).OrderBy(Function(r) r.Index).ToArray, DragDropEffects.All)
End If
End Sub
datagridview2
Private Sub datagridview2_DragEnter(sender As Object, e As DragEventArgs) Handles datagridview2.DragEnter
e.Effect = DragDropEffects.All
End Sub
Private Sub datagridview2_DragDrop(sender As Object, e As DragEventArgs) Handles datagridview2.DragDrop
Try
Dim Rows() As DataGridViewRow = DirectCast(e.Data.GetData(GetType(DataGridViewRow())), DataGridViewRow())
For Each row As DataGridViewRow In rows
MsgBox(row.Cells("ID").Value)
Next
Catch ex As Exception
End Try
End Sub
but there is an error in conversion.
any ideas?
Try sending a copy of the selected rows instead:
Dim dgrCopy(datagridview1.SelectedRows.Count - 1) As DataGridViewRow
datagridview1.SelectedRows.CopyTo(dgrCopy, 0)
Me.datagridview1.DoDragDrop(dgrCopy.OrderBy(Function(r) r.Index).ToArray, DragDropEffects.All)

Display text for drag and drop images VB.NET

I am developing a simple SQL generator for images. I am having issues getting texts to be displayed in a textbox when I drag pictures into a PictureBox. Am I doing anything wrong? I want a situation when I drag the image into the PictureBox, the textbox shown in blue should display: 'SELECT FROM EMPLOYEE;'. I need help to get this code working. My code is displayed below.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'' picDropTarget.AllowDrop = True
picAccept.AllowDrop = True
End Sub
Private Sub picSELECT_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picSELECT.MouseDown, picEMPLOYEE.MouseDown
' Start the drag if it's the left mouse button.
If (e.Button = MouseButtons.Left) Then
Dim source As PictureBox = DirectCast(sender, PictureBox)
picSELECT.DoDragDrop(source.Image, DragDropEffects.Copy)
'Added this line to show
'txtSQL.Text = "SELECT"
End If
End Sub
Private Sub picAccept_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles picAccept.DragEnter
' See if this is a copy and the data includes an image.
If (e.Data.GetDataPresent(DataFormats.Bitmap) AndAlso
(e.AllowedEffect And DragDropEffects.Copy) <> 0) _
Then
' Allow this.
'e.Effect = DragDropEffects.All
e.Effect = DragDropEffects.All
Else
' Don't allow any other drop.
' e.Effect = DragDropEffects.None
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub picAccept_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles picAccept.DragDrop, picSELECT.DragDrop, picEMPLOYEE.DragDrop
Dim bm As Bitmap = DirectCast(e.Data.GetData(DataFormats.Bitmap, True), Bitmap)
picAccept.Image = bm
End SubEnd Class
TextBox1.Text = "select from EMPLOYEES"
Here's a fully working minimal sample. You can copy/paste the below, drop a file into the PictureBox at the bottom of the form, and the TextBox at the top will get populated with text.
Public Class Form1
Dim txtbx As New TextBox
Dim pctbx As New PictureBox
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
txtbx.Dock = DockStyle.Top
pctbx.Dock = DockStyle.Bottom
pctbx.BackColor = Color.AntiqueWhite
pctbx.AllowDrop = True
Controls.Add(txtbx)
Controls.Add(pctbx)
AddHandler pctbx.DragEnter, AddressOf pctbx_DragEnter
AddHandler pctbx.DragDrop, AddressOf pctbx_DragDrop
End Sub
Private Sub pctbx_DragEnter(sender As Object, e As DragEventArgs)
e.Effect = DragDropEffects.All
End Sub
Private Sub pctbx_DragDrop(sender As Object, e As DragEventArgs)
txtbx.Text = "select from employees where id = "
End Sub
End Class

Cancelling of Drag/Drop on DataGridView

I am using basic Drag/Drop functionality in single DataGridView.
Like this:
Private Sub DataGridView1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragDrop
Dim p As Point = Me.PointToClient(New Point(e.X, e.Y))
dropindex = DataGridView1.HitTest(p.X, p.Y).RowIndex
If (e.Effect = DragDropEffects.Move) Then
Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow)
'' SOME PROCEDURE HERE FOR DROPPING ---
End If
End Sub
Private Sub DataGridView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragOver
e.Effect = DragDropEffects.Move
End Sub
Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown
dragindex = DataGridView1.HitTest(e.X, e.Y).RowIndex
If dragindex > -1 Then
Dim dragSize As Size = SystemInformation.DragSize
dragrect = New Rectangle(New Point(CInt(e.X - (dragSize.Width / 2)), CInt(e.Y - (dragSize.Height / 2))), dragSize)
Else
dragrect = Rectangle.Empty
End If
End Sub
Private Sub DataGridView1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseMove
If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
If (dragrect <> Rectangle.Empty AndAlso Not dragrect.Contains(e.X, e.Y)) Then
Me.DoDragDrop(DataGridView1.Rows(dragindex), DragDropEffects.Move)
End If
End If
End Sub
When I push left mouse button and start to drag some square appears under a cursor and dragging begins.
If I release button on certain row dropping occurs (normally:)
But, if during dragging I change a mind and press ESC key those square under cursor dissappears but dropping occurs anyway when I release button.
What to do to cancel dropping when dragging already begins (say with ESC key)?
Me.DoDragDrop(DataGridView1.Rows(dragindex), DragDropEffects.Move)
You made a mistake there. The QueryContinueDrag event is raised on the control that called DoDragDrop(). You used Me, making the form the source of the data. But you implemented the QueryContinueDrag for DataGridView1, not the form. So your event handler never runs. Fix:
DataGridView1.DoDragDrop(DataGridView1.Rows(dragindex), DragDropEffects.Move)
You cannot track ESC by relying on the Key Event methods of the DataGridView, because are not triggered while you are drag-dropping. But there is an easy way to account for this situation (drag-drop process interrupted): DragLeave Event. You can make the condition for dropping depend upon a global flag set in this method. Sample code:
Dim cancelDrop As Boolean
Private Sub DataGridView1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragDrop
Dim p As Point = Me.PointToClient(New Point(e.X, e.Y))
dropindex = DataGridView1.HitTest(p.X, p.Y).RowIndex
If (e.Effect = DragDropEffects.Move AndAlso Not cancelDrop) Then
Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow)
'' SOME PROCEDURE HERE FOR DROPPING ---
End If
cancelDrop = False
End Sub
Private Sub DataGridView1_DragLeave(sender As Object, e As System.EventArgs) Handles DataGridView1.DragLeave
cancelDrop = True
End Sub