DGV DragDrop - исчезновение строк - PullRequest
4 голосов
/ 18 ноября 2011

Я пытаюсь написать некоторый код, чтобы позволить пользователям моего приложения перетаскивать строки в DataGridView, чтобы изменить их порядок.Проблема в том, что перетаскиваемая строка исчезает при ее удалении, поэтому перетаскивание приводит к удалению этой строки.Вот мой код:

  private Rectangle dragBoxFromMouseDown;
        private int rowIndexFromMouseDown;
        private int rowIndexOfItemUnderMouseToDrop;

        private void grdCons_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
                {
                    DragDropEffects dropEffect = grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
                }
            }
        }

        private void grdCons_MouseDown(object sender, MouseEventArgs e)
        {
            rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
            if (rowIndexFromMouseDown != -1)
            {
                Size dragSize = SystemInformation.DragSize;
                dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
            }
            else
            {
                dragBoxFromMouseDown = Rectangle.Empty;
            }
        }

        private void grdCons_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }

        private void grdCons_DragDrop(object sender, DragEventArgs e)
        {
            Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
            rowIndexOfItemUnderMouseToDrop = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

            if (e.Effect == DragDropEffects.Move)
            {
                DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
                grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
                grdCons.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);
            }
        }

По-видимому, вставка в DGV в событии DragDrop не работает.

Ответы [ 2 ]

0 голосов
/ 03 июля 2012

Проблема заключается в grdCons_DragDrop().Поскольку вы упомянули, что DGV привязан к DataTable, вызов grdCons.Rows.Insert(targetIndex, rowToMove) вызовет InvalidOperationException.Когда DGV привязан к данным, вам нужно манипулировать DataSource, а не DGV.Вот правильный способ звонить grdCons_DragDrop().

private void grdCons_DragDrop(object sender, DragEventArgs e)
{
    DataTable tbl = (DataTable)grdCons.DataSource;
    Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
    int targetIndex = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

    if (e.Effect == DragDropEffects.Move)
    {
        DataRow row = tbl.NewRow();
        row.ItemArray = tbl.Rows[rowIndexFromMouseDown].ItemArray; //copy the elements
        tbl.Rows.RemoveAt(rowIndexFromMouseDown);
        tbl.Rows.Insert(targetIndex, rowToMove);
    }
}
0 голосов
/ 18 ноября 2011

Вот исправленная версия вашего кода, которая работает:

  public Form1()
  {
     InitializeComponent();
     grdCons.Rows.Add(7);
     for (int i = 0; i < grdCons.Rows.Count; i++)
     {
        grdCons.Rows[i].Cells[0].Value = i;
        grdCons.Rows[i].Cells[1].Value = "Cell " + i;
     }
     grdCons.AllowDrop = true;
     grdCons.AllowUserToAddRows = false;
     grdCons.AllowUserToDeleteRows = false;
     grdCons.MouseMove += new MouseEventHandler(grdCons_MouseMove);
     grdCons.MouseDown += new MouseEventHandler(grdCons_MouseDown);
     grdCons.DragOver += new DragEventHandler(grdCons_DragOver);
     grdCons.DragDrop += new DragEventHandler(grdCons_DragDrop);
  }

  private int rowIndexFromMouseDown;

  private void grdCons_MouseMove(object sender, MouseEventArgs e)
  {
     if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
     {
        grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
     }
  }

  private void grdCons_MouseDown(object sender, MouseEventArgs e)
  {
     rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
  }

  private void grdCons_DragOver(object sender, DragEventArgs e)
  {
     e.Effect = DragDropEffects.Move;
  }

  private void grdCons_DragDrop(object sender, DragEventArgs e)
  {
     Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
     int targetIndex = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

     if (e.Effect == DragDropEffects.Move)
     {
        DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
        grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
        grdCons.Rows.Insert(targetIndex, rowToMove);
     }
  }
...