Перетаскивание не работает в C # - PullRequest
1 голос
/ 30 августа 2011

Я понял, как перетаскивать строки между сеточными представлениями из , как перетаскивать строку сетки в одну сетку на другую , но теперь у меня возникла проблема. Я могу перетащить строку из gridPODetails в DataGridView1. Я могу перетащить строку обратно в gridPODetails из DataGridView1. Но после этого я ничего не получаю. Я ожидал, что смогу тянуть туда и обратно неопределенно, но я могу идти только туда и обратно. Что может быть причиной этого и как исправить?

 private void gridPODetails_MouseDown(object sender, MouseEventArgs e)
        {
            DataGridView.HitTestInfo info = gridPODetails.HitTest(e.X, e.Y);

            if (info.RowIndex >= 0)
            {
                DataRow view = ((DataTable)(gridPODetails.DataSource)).Rows[info.RowIndex];
                if (view != null)
                {
                    gridPODetails.DoDragDrop(view, DragDropEffects.Copy);
                }
            }
        }

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

        private void gridPODetails_DragDrop(object sender, DragEventArgs e)
        {
            DataGridView grid = sender as DataGridView;
            DataTable table = grid.DataSource as DataTable;
            DataRow row = e.Data.GetData(typeof(DataRow)) as DataRow;

            if (row != null && table != null && row.Table != table)
            {
                table.ImportRow(row);
                row.Delete();
            }
        }

        private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
        {
            DataGridView.HitTestInfo info = dataGridView1.HitTest(e.X, e.Y);

            if (info.RowIndex >= 0)
            {
                DataRow view = ((DataTable)(dataGridView1.DataSource)).Rows[info.RowIndex];
                if (view != null)
                {
                    dataGridView1.DoDragDrop(view, DragDropEffects.Copy);
                }
            }
        }

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

        private void dataGridView1_DragDrop(object sender, DragEventArgs e)
        {
            DataGridView grid = sender as DataGridView;
            DataTable table = grid.DataSource as DataTable;
            DataRow row = e.Data.GetData(typeof(DataRow)) as DataRow;

            if (row != null && table != null && row.Table != table)
            {
                table.ImportRow(row);
                row.Delete();
            }
        }

Ответы [ 2 ]

2 голосов
/ 31 августа 2011

В ответ на комментарий MAW74656 к вопросу о том, что я собрал метод, который я использовал бы, если бы собирался подключить несколько сеток для выполнения перетаскивания.

По сути, я стараюсьсоздать лямбду, чтобы сгруппировать все эти функциональные возможности внутри одного метода - это можно сделать как собственный метод, если необходимо разрешить несколько вызывающих абонентов.

Вот оно:

Func<DataGridView, IEnumerable<Action>> configureDragDrop = grid =>
{
    var dataTable = grid.DataSource as DataTable;

    /* Event handler definitions here - see below */

    grid.MouseDown += mds;
    grid.DragEnter += des;
    grid.DragDrop += dds;

    return new Action[]
    {
        () => grid.MouseDown -= mds,
        () => grid.DragEnter -= des,
        () => grid.DragDrop -= dds,
    };
};

Этот код позволяет мне написать это:

        // form-level field
        private List<Action> removeHandlers = new List<Action>();

        // in the method where `configureDragDrop` is defined
        removeHandlers.AddRange(configureDragDrop(gridPODetails));
        removeHandlers.AddRange(configureDragDrop(dataGridView1));
        removeHandlers.AddRange(configureDragDrop(dataGridView2));
        removeHandlers.AddRange(configureDragDrop(dataGridView3));
        removeHandlers.AddRange(configureDragDrop(dataGridView4));
        removeHandlers.AddRange(configureDragDrop(dataGridView5));
        removeHandlers.AddRange(configureDragDrop(dataGridView6));
        removeHandlers.AddRange(configureDragDrop(dataGridView7));
        // etc

Когда я закрываю свою форму, я могу удалить все обработчики в одну строку:

        Array.ForEach(removeHandlers.ToArray(), rh => rh.Invoke());

Внешний вид обработчиков событийочень похоже на исходный код - только сейчас в лямбда-форме.

MouseDown:

            MouseEventHandler mds = (smd, emd) =>
            {
                var info = grid.HitTest(emd.X, emd.Y);
                if (info.RowIndex >= 0)
                {
                    var dr = dataTable.Rows[info.RowIndex];
                    if (dr != null)
                    {
                        grid.DoDragDrop(dr, DragDropEffects.Copy);
                    }
                }
            };

DragEnter:

            DragEventHandler des = (sde, ede) =>
            {
                ede.Effect = DragDropEffects.Copy;
            };

DragDrop:

            DragEventHandler dds = (sdd, edd) =>
            {
                var dr = edd.Data.GetData(typeof(DataRow)) as DataRow;
                if (dr != null)
                {
                    var dst = dataTable;
                    var src = dr.Table;
                    if (dst != src)
                    {
                        dst.ImportRow(dr);
                        dr.Delete();
                        src.AcceptChanges();
                        dst.AcceptChanges();
                    }
                }
            };

Надеюсь, это поможет.

2 голосов
/ 31 августа 2011

Добавление table.AcceptChanges() после row.Delete() должно позволить вам переместить строку назад между таблицами.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...