private void OnRowDragOver(int rowIndex)
        {
            // 如果和上次导致重绘的行是同一行则无需重绘
            if (m_intIndexOfItemUnderMouseOver == rowIndex)
            {
                return;
            }

            int old = m_intIndexOfItemUnderMouseOver;

            m_intIndexOfItemUnderMouseOver = rowIndex;

            // 去掉原有行的红线
            if (old > -1)
            {
                Dgv_Main.InvalidateRow(old);
            }

            // 绘制新行的红线
            if (rowIndex > -1)
            {
                Dgv_Main.InvalidateRow(rowIndex);
            }

            if (rowIndex == -1)
            {
                Dgv_Main.CurrentCell = Dgv_Main.Rows[m_intIndexOfItemUnderMouseToDrop].Cells["零件编码"];
            }
        }
        private void dataGridView_MouseMove(object sender, MouseEventArgs e)
        {
            // 不是鼠标左键按下时移动
            if ((e.Button & MouseButtons.Left) != MouseButtons.Left)
            {
                return;
            }

            // 如果鼠标在不启用拖动的范围内
            if (m_dragBoxFromMouseDown == Rectangle.Empty || m_dragBoxFromMouseDown.Contains(e.X, e.Y))
            {
                return;
            }

            // 如果源数据行索引值不正确
            if (m_intIndexOfItemUnderMouseToDrag < 0)
            {
                return;
            }

            // 开始拖动,第一个参数表示要拖动的数据,可以自定义,一般是源数据行
            var             row        = Dgv_Main.Rows[m_intIndexOfItemUnderMouseToDrag];
            DragDropEffects dropEffect = Dgv_Main.DoDragDrop(row, DragDropEffects.All);

            //拖动过程结束后清除拖动位置行的红线效果
            OnRowDragOver(-1);
        }
        private void dataGridView_DragOver(object sender, DragEventArgs e)
        {
            // 把屏幕坐标转换成控件坐标
            Point p = Dgv_Main.PointToClient(new Point(e.X, e.Y));

            // 通过鼠标按下的位置获取所在行的信息
            // 如果不是在数据行或者在源数据行上则不能作为拖放的目标
            var hitTest = Dgv_Main.HitTest(p.X, p.Y);

            if (hitTest.Type != DataGridViewHitTestType.Cell || hitTest.RowIndex == m_intIndexOfItemUnderMouseToDrag)
            {
                e.Effect = DragDropEffects.None;
                OnRowDragOver(-1);
                return;
            }

            // 设置为作为拖放移动的目标
            e.Effect = DragDropEffects.Move;
            // 通知目标行重绘
            OnRowDragOver(hitTest.RowIndex);
        }
        private void dataGridView_MouseDown(object sender, MouseEventArgs e)
        {
            // 通过鼠标按下的位置获取所在行的信息
            var hitTest = Dgv_Main.HitTest(e.X, e.Y);

            if (hitTest.Type != DataGridViewHitTestType.Cell)
            {
                return;
            }

            // 记下拖动源数据行的索引及已鼠标按下坐标为中心的不会开始拖动的范围
            m_intIndexOfItemUnderMouseToDrag = hitTest.RowIndex;

            if (m_intIndexOfItemUnderMouseToDrag > -1)
            {
                Size dragSize = SystemInformation.DragSize;
                m_dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
            }
            else
            {
                m_dragBoxFromMouseDown = Rectangle.Empty;
            }
        }
        private void dataGridView_DragDrop(object sender, DragEventArgs e)
        {
            DataTable dtTemp = (DataTable)Dgv_Main.DataSource;

            // 把屏幕坐标转换成控件坐标
            Point p = Dgv_Main.PointToClient(new Point(e.X, e.Y));

            // 如果当前位置不是数据行
            // 或者刚好是源数据行的下一行(本示例中假定拖放操作为拖放至目标行的上方)
            // 则不进行任何操作
            var hitTest = Dgv_Main.HitTest(p.X, p.Y);

            if (hitTest.Type != DataGridViewHitTestType.Cell || hitTest.RowIndex == m_intIndexOfItemUnderMouseToDrag + 1)
            {
                return;
            }

            m_intIndexOfItemUnderMouseToDrop = hitTest.RowIndex;

            // * 执行拖放操作(执行的逻辑按实际需要)

            var tempRow = dtTemp.NewRow();

            tempRow.ItemArray = dtTemp.Rows[m_intIndexOfItemUnderMouseToDrag].ItemArray;
            dtTemp.Rows.RemoveAt(m_intIndexOfItemUnderMouseToDrag);

            if (m_intIndexOfItemUnderMouseToDrag < m_intIndexOfItemUnderMouseToDrop)
            {
                m_intIndexOfItemUnderMouseToDrop--;
            }

            dtTemp.Rows.InsertAt(tempRow, m_intIndexOfItemUnderMouseToDrop);
            dtTemp.AcceptChanges();
            Dgv_Main.DataSource = dtTemp;

            //Dgv_Main.FirstDisplayedScrollingRowIndex = m_intIndexOfItemUnderMouseToDrop;
        }