How to Drag And Drop selected rows between DataGridViews - vb.net

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)

Related

Datagridview - edit selected row?

I have set Datagridview .ReadOnly property to True, and then added a button column. Button column is meant for edit button when clicked, but I wish to edin only currently selected row. This is what I tried:
EDIT:
Public Class Form2
Private Sub Form2_Resize(sender As Object, e As EventArgs) Handles Me.Resize
Me.DataGridView1.Height = 0.8 * Me.Height
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'Users._USERS' table. You can move, or remove it, as needed.
Me.USERSTableAdapter.Fill(Me.Users._USERS)
Me.DataGridView1.DefaultCellStyle.Font = New Font("Arial", 7)
End Sub
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
For i As Integer = 0 To DataGridView1.Rows.Count - 1
DataGridView1.Rows(i).ReadOnly = True
Next
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim yourColumnIndex As Int32 = 3
If e.ColumnIndex = yourColumnIndex Then
If MsgBox("Do you wish to edit records?", vbQuestion + vbYesNo, "Edit records") = vbYes Then
DataGridView1.Rows(e.RowIndex).ReadOnly = False
End If
End If
End Sub
Private Sub DataGridView1_RowLeave(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.RowLeave
DataGridView1.Rows(e.RowIndex).ReadOnly = True
End Sub
End Class
You can't set the grid's ReadOnly property to true. After the rows are added to the grid, you would have to loop through your rows and set the ReadOnly property for each row:
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
For i As Integer = 0 To DataGridView1.Rows.Count - 1
DataGridView1.Rows(i).ReadOnly = True
Next
End Sub
Note: you can't set these properties in the form's constructor, a quirk of the DataGridView control.
Then use the RowIndex property provided by the e parameter:
Private Sub DataGridView1_CellContentClick(sender As Object,
e As DataGridViewCellEventArgs)
Handles DataGridView1.CellContentClick
If e.ColumnIndex = 3 Then
DataGridView1.Rows(e.RowIndex).ReadOnly = False
End If
End Sub
Set it back to true when leaving the row:
Private Sub DataGridView1_RowLeave(sender As Object,
e As DataGridViewCellEventArgs)
Handles DataGridView1.RowLeave
DataGridView1.Rows(e.RowIndex).ReadOnly = True
End Sub
This is working, I just changed your suggestion a little bit (DatagridView Readonly property must be set to False):
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
For Each band As DataGridViewBand In DataGridView1.Columns
band.ReadOnly = True
Next
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim yourColumnIndex As Int32 = 3
If e.ColumnIndex = yourColumnIndex Then
If MsgBox("Do you wish to edit record?", vbQuestion + vbYesNo, "Edit record") = vbYes Then
For Each band As DataGridViewBand In DataGridView1.Columns
band.ReadOnly = False
Next
End If
End If
End Sub
Private Sub DataGridView1_RowLeave(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.RowLeave
For Each band As DataGridViewBand In DataGridView1.Columns
band.ReadOnly = True
Next
End Sub
Thanks for all your help Lars!

drag and drop listview to textbox

I am currently creating an application that populates a listbox from a database table. What I would like to do is be able to drag an item from the listbox to a textbox. When I drag an item over from the listbox and drop it in the textbox what drops in the textbox is System.Data.DataRowView. I'm not sure why this is happening.
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
sqlselectpart = "Select fpartno from inmast"
Try
If connection.State = 0 Then
connection.Open()
End If
DS.Clear()
adapter = New SqlDataAdapter(sqlselectpart, connection)
adapter.Fill(DS, "fpartno")
ListBox1.DataSource = DS.Tables("fpartno")
ListBox1.DisplayMember = "fpartno"
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub ListBox1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left AndAlso Me.ListBox1.SelectedItem IsNot Nothing Then
Me.ListBox1.DoDragDrop(Me.ListBox1.SelectedItem.ToString(), DragDropEffects.Copy)
End If
End Sub
Private Sub TextBox1_DragEnter(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles TextBox1.DragEnter
If (e.Data.GetDataPresent(DataFormats.Text)) Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub TextBox1_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles TextBox1.DragDrop
TextBox1.Text = e.Data.GetData(DataFormats.Text)
End Sub

open selected row in datagridview to edit in Another form

I am using vb.net designer to connect to access database .
On my Form1 I have a DataGridView And Two Button For Add And Edit
I Make Form2 To Add Data Into Database And Worked OK ..
Imake Form3 Wiht Same form2 Content
Now I need When i selcet row in DataGridView And Clic Edit Button The data of selected row show on form3 for Edit it
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SalesTableAdapter.Fill(Me.OrdersDataSet.sales)
Me.DateTimePicker1.Value = Date.Today
End Sub
Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
SalesBindingSource.Filter = String.Format("date = '{0}'", DateTimePicker1.Value.ToShortDateString())
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.Show()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
End Sub
Private Sub SalesDataGridView_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles SalesDataGridView.CellContentClick
End Sub
End Class
You need to approach this in a modal/dialog way. You only need one form for both add and edit.
Add/Edit form
Add a parameterized constructor to the form.
Public Sub New(row As DataRowView)
Me.InitializeComponent()
'Me.ctlAge: NumericUpDown control.
'Me.ctlBirthday: DateTimePicker control.
'Me.ctlName: TextBox control.
If (row Is Nothing) Then
'Add mode, set default values:
Me.ctlAge.Value = 0
Me.ctlBirthday.Value = Date.Now
Me.ctlName.Text = String.Empty
Else
'Edit mode, set current values:
Me.ctlAge.Value = CDec(row.Item("AGE"))
Me.ctlBirthday.Value = CDate(row.Item("BIRTHDAY"))
Me.ctlName.Text = CStr(row.Item("NAME"))
End If
End Sub
You also need an accept button and a cancel button.
Friend Sub btnAcceptClicked(sender As Object, e As EventArgs) Handles btnAccept.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
End Sub
Friend Sub btnCancelClicked(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.DialogResult = Windows.Forms.DialogResult.Cancel
Me.Close()
End Sub
Main form
Add method:
Private Sub btnAddClicked(sender As Object, e As EventArgs) Handles btnAdd.Click
Try
Using f As New AddOrEditForm(CType(Nothing, DataRowView))
If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
Dim view As DataView = TryCast(Me.SalesDataGridView.DataSource, DataView)
If (view Is Nothing) Then
Throw New InvalidCastException()
End If
Dim viewRow As DataRowView = view.AddNew()
viewRow.EndEdit()
viewRow.Item("AGE") = f.ctlAge.Value
viewRow.Item("BIRTHDAY") = f.ctlBirthday.Value
viewRow.Item("NAME") = f.ctlName.Text
viewRow.EndEdit()
End If
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Edit method:
Private Sub btnEditClicked(sender As Object, e As EventArgs) Handles btnEdit.Click
Try
Me.SalesDataGridView.EndEdit()
If (Me.SalesDataGridView.SelectedRows.Count > 0) Then
Dim gridRow As DataGridViewRow = Me.SalesDataGridView.SelectedRows(0)
Dim viewRow As DataRowView = TryCast(gridRow.DataBoundItem, DataRowView)
If (viewRow Is Nothing) Then
Throw New InvalidCastException()
End If
Using f As New AddOrEditForm(viewRow)
If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
viewRow.BeginEdit()
Try
viewRow.Item("AGE") = f.ctlAge.Value
viewRow.Item("BIRTHDAY") = f.ctlBirthday.Value
viewRow.Item("NAME") = f.ctlName.Text
viewRow.EndEdit()
Catch ex As Exception
viewRow.CancelEdit()
Throw ex
End Try
End If
End Using
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

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

Drag data from DG and other controls to another DG in 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