{"id":107,"date":"2024-12-05T20:15:55","date_gmt":"2024-12-05T20:15:55","guid":{"rendered":"https:\/\/code.handwerkit.com\/?p=107"},"modified":"2025-02-20T14:31:42","modified_gmt":"2025-02-20T14:31:42","slug":"c-richtextbox-wordwrap-2","status":"publish","type":"post","link":"https:\/\/code.handwerkit.com\/?p=107","title":{"rendered":"C# DataGridView Drag and Drop"},"content":{"rendered":"\n<p class=\"has-normal-font-size\">Ein DateGridView mit Drag and Drop der gesamten Zeile.<br>&#8211; Multiselect m\u00f6glich (verschiebt alle markierten Zeilen)<br>&#8211; Beh\u00e4llt die selektieren Zeilen nach dem ablegen<br>&#8211; Zeigt einen visuellen Strich am Einf\u00fcgepunkt ober oder unterhalb der Zeile<br>&#8211; Scrollt automatisch hoch\/runter<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism off-numbers lang-csharp\" data-file=\"saveUpdateEntity\" data-lang=\"C#\" data-show-lang=\"1\"><code>\n \/\/works with multiselect rows\n \/\/shows divider\n \/\/todo after dragover click on multiselect rows deselect it\n private static int rowIndexFrom = -1;\n private static int rowIndexTo = -1;\n private static int[] dataGridViewSelectedRows = null;\n private void dataGridView1_Paint(object sender, PaintEventArgs e)\n {\n     if (rowIndexTo == -1) return;\n     var dataGridView = sender as DataGridView;\n     var rect = dataGridView1.GetRowDisplayRectangle(rowIndexTo, false);\n     int posY = (rowIndexTo > rowIndexFrom && !dataGridView.Rows[rowIndexTo].IsNewRow)\n                ? rect.Bottom : rect.Top;\n     using (var pen = new Pen(Color.FromArgb(150, 33, 186, 71), 7))\n         e.Graphics.DrawLine(pen, new Point(rect.Left, posY - 1), new Point(rect.Right, posY - 1));\n     \n }\n private void dataGridView1_MouseMove(object sender, MouseEventArgs e)\n {\n }\n private void dataGridView1_MouseDown(object sender, MouseEventArgs e)\n {\n     if ((e.Button & MouseButtons.Left) != MouseButtons.Left) { rowIndexTo = -1; return; }\n     var dataGridView = sender as DataGridView;\n     if (!dataGridView1.AllowDrop || dataGridView.ReadOnly || dataGridView.SelectedRows.Count == 0) { rowIndexTo = -1; return; }\n     var hitTestInfo = dataGridView.HitTest(e.X, e.Y);\n     if (hitTestInfo.ColumnIndex == -1)\n     {\n         \n     }\n     foreach (DataGridViewRow row in dataGridView.SelectedRows)\n         if (row.IsNewRow) row.Selected = false;\n     dataGridViewSelectedRows = dataGridView.SelectedRows.Cast<DataGridViewRow>().Select(row => row.Index).ToArray();\n     if (dataGridView1.SelectedRows.Count == 0) { rowIndexFrom = -1; return; }\n     rowIndexFrom = hitTestInfo.RowIndex;\n     if (dataGridViewSelectedRows.Contains(rowIndexFrom))\n     {\n         dataGridView.EndEdit();\n         Task.Factory.StartNew(() =>\n         {\n             dataGridView.Invoke(new Action(() =>\n             {\n                 if (dataGridViewSelectedRows?.Length > 1)\n                     foreach (int row in dataGridViewSelectedRows) dataGridView.Rows[row].Selected = true;\n                 if (rowIndexFrom != -1 && dataGridView.Rows.Count >= dataGridViewSelectedRows?.Length)\n                     dataGridView.DoDragDrop(0, DragDropEffects.Move);\n             }));\n         });\n     }\n }\n private void dataGridView1_DragOver(object sender, DragEventArgs e)\n {\n     if (rowIndexFrom == -1) return;\n     var dataGridView = sender as DataGridView;\n     if (!dataGridView.AllowDrop || dataGridView.ReadOnly || dataGridView.SelectedRows.Count <= 0) { rowIndexTo = -1; return; }\n     e.Effect = DragDropEffects.Move;\n     try\n     {\n        \n         Point clientPointer = dataGridView.PointToClient(new Point(e.X, e.Y));\n         rowIndexTo = dataGridView.HitTest(clientPointer.X, clientPointer.Y).RowIndex;\n         if (dataGridView.Rows[rowIndexTo].IsNewRow) { rowIndexTo--; }\n         \n     }\n     catch\n     {\n         rowIndexTo = -1;\n     }\n     if (dataGridViewSelectedRows?.Length > 1 && dataGridViewSelectedRows.Contains(rowIndexTo) && dataGridViewSelectedRows.Contains(rowIndexTo - 1))\n     {\n         rowIndexTo = -1;\n     }\n     #region Scrollen beim Verschieben von Zeilen\n     Point clientPoint = dataGridView.PointToClient(new Point(e.X, e.Y));\n     \/\/Converts window position to user control position (otherwise you can use MousePosition.Y)\n     int mousepos = PointToClient(Cursor.Position).Y;\n     \/\/If the mouse is hovering over the bottom 5% of the grid\n     if (mousepos > (dataGridView1.Location.Y + (dataGridView1.Height * 0.95)))\n     {\n         mouseMoveDown = true;\n         \/\/If the first row displayed isn't the last row in the grid\n         if (dataGridView1.FirstDisplayedScrollingRowIndex < dataGridView1.RowCount - 1)\n         {\n             \/\/Increase the first row displayed index by 1 (scroll down 1 row)\n             int firstDisplRow = dataGridView1.FirstDisplayedScrollingRowIndex;\n             if (dataGridView1.Rows[firstDisplRow + 1].Displayed)\n             {\n                 Thread.Sleep(60);\n                 dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.FirstDisplayedScrollingRowIndex + 1;\n             }\n         }\n     }\n     \/\/If the mouse is hovering over the top 5% of the grid\n     if (mousepos < (dataGridView1.Location.Y + (dataGridView1.Height * 0.55)))\n     {\n         mouseMoveDown = false;\n         \/\/If the first row displayed isn't the first row in the grid\n         if (dataGridView1.FirstDisplayedScrollingRowIndex > 1)\n         {\n             int firstDisplRow = dataGridView1.FirstDisplayedScrollingRowIndex;\n             Thread.Sleep(60);\n             dataGridView1.FirstDisplayedScrollingRowIndex -= 1;\n         }\n     }\n     #endregion\n     dataGridView.Refresh();\n }\n private void dataGridView1_DragDrop(object sender, DragEventArgs e)\n {\n     if (rowIndexTo == -1) return;\n     var dataGridView = sender as DataGridView;\n     if (!dataGridView.AllowDrop || dataGridView.ReadOnly || dataGridView.SelectedRows.Count <= 0) { rowIndexTo = -1; dataGridView.Refresh(); return; }\n     if (rowIndexTo == rowIndexFrom &#038;&#038; dataGridView.SelectedRows.Count == 1) { rowIndexTo = -1; dataGridView.Refresh(); return; }\n     if (rowIndexTo == -1) { dataGridView.Refresh(); return; }\n     if (e.Effect == DragDropEffects.Move)\n     {\n         dataGridView.Invoke(new Action(() =>\n         {\n             List<DataGridViewRow> rowsToMove = dataGridView.SelectedRows.Cast<DataGridViewRow>().OrderBy(row => row.Index).ToList();\n             bool indexInbetweenRows = rowIndexTo > rowsToMove.Min(row => row.Index) && rowIndexTo < rowsToMove.Max(row => row.Index);\n             if (indexInbetweenRows) rowIndexTo = rowsToMove.Min(row => row.Index);\n             rowIndexTo = rowIndexFrom >= rowIndexTo ? rowIndexTo : rowIndexTo - (rowsToMove.Count - 1);\n             foreach (DataGridViewRow row in rowsToMove) dataGridView.Rows.Remove(row);\n             int insertIndex = rowIndexTo;\n             rowsToMove.ForEach(row => dataGridView.Rows.Insert(insertIndex++, row));\n             dataGridView.ClearSelection();\n             dataGridView.CurrentCell = dataGridView.Rows[rowIndexTo].Cells[dataGridView.FirstDisplayedCell.ColumnIndex];\n             rowsToMove.ForEach(row => row.Selected = true);\n         }));\n     }\n     rowIndexTo = -1;\n     dataGridView.Refresh();\n }\n private void dataGridView1_MouseLeave(object sender, EventArgs e)\n {\n     rowIndexTo = -1; \n     dataGridView1.Refresh();\n }\n<\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"524\" height=\"306\" src=\"http:\/\/code.handwerkit.com\/wp-content\/uploads\/2024\/12\/ezgif-1-cfcc414623.gif\" alt=\"\" class=\"wp-image-118\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Ein DateGridView mit Drag and Drop der gesamten Zeile.&#8211; Multiselect m\u00f6glich (verschiebt alle markierten Zeilen)&#8211; Beh\u00e4llt die selektieren Zeilen nach dem ablegen&#8211; Zeigt einen visuellen Strich am Einf\u00fcgepunkt ober oder unterhalb der Zeile&#8211; Scrollt automatisch hoch\/runter<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13,3],"tags":[6,35,36,37],"class_list":["post-107","post","type-post","status-publish","format-standard","hentry","category-c-net","category-winform","tag-c","tag-datagridview","tag-drag-and-drop","tag-rows","entry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false},"uagb_author_info":{"display_name":"Rooout","author_link":"https:\/\/code.handwerkit.com\/?author=1"},"uagb_comment_info":3,"uagb_excerpt":"Ein DateGridView mit Drag and Drop der gesamten Zeile.&#8211; Multiselect m\u00f6glich (verschiebt alle markierten Zeilen)&#8211; Beh\u00e4llt die selektieren Zeilen nach dem ablegen&#8211; Zeigt einen visuellen Strich am Einf\u00fcgepunkt ober oder unterhalb der Zeile&#8211; Scrollt automatisch hoch\/runter","_links":{"self":[{"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=\/wp\/v2\/posts\/107","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=107"}],"version-history":[{"count":6,"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=\/wp\/v2\/posts\/107\/revisions"}],"predecessor-version":[{"id":129,"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=\/wp\/v2\/posts\/107\/revisions\/129"}],"wp:attachment":[{"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=107"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=107"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code.handwerkit.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=107"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}