none
2つのdatagridview間のドラッグ&ドロップによるデータの移動するには RRS feed

  • 質問

  • どうしたらいいのでしょうか?

     

    コードは下記です。

     

    private void dataGridView3_MouseDown(object sender, MouseEventArgs e)
            {
                DataGridView.HitTestInfo hit = dataGridView3.HitTest(e.X, e.Y);
                dataGridView3.DoDragDrop(dataGridView3.Rows[hit.RowIndex], DragDropEffects.Copy);
            }

            private void dataGridView4_DragEnter(object sender, DragEventArgs e)
            {
                e.Effect = DragDropEffects.Copy;
            }
            private void dataGridView4_DragDrop(object sender, DragEventArgs e)
            {
                Point clientPoint = dataGridView4.PointToClient(new Point(e.X, e.Y));
                DataGridView.HitTestInfo hit = dataGridView4.HitTest(clientPoint.X, clientPoint.Y);

                Type myType = dataGridView3.Rows.GetType();
                if (hit.RowIndex != -1)
                {
                    dataGridView4.Rows.Insert(hit.RowIndex, e.Data.GetData(myType));
                }
                else
                {
                    dataGridView4.Rows.Add(e.Data.GetData(myType));
                }
            }

    ※datagridview3は移動元でdatagridview4が移動先です。

     

    このコードでテストすると、DragDropイベントの

    dataGridView4.Rows.Insert(hit.RowIndex, e.Data>GetDat(myType));

    の所でエラーにはならず、フォームが現れてしまいます。

     

    全世界のこのトピックに関するサイトを見たのですが、何人もの開発者が全く同じコードを

    試して問題が解決されていないようです。。。

    2008年1月9日 3:28

回答

  • 書かれたコードですが、dataGridView3.Rows[hit.RowIndex] と dataGridView3.Rows.GetType() は型が違うのでマズイです。
    それと、Insert や Add メソッドに、他のグリッドの DataGridViewRow を渡すのもダメそうです。

     

    非バインドの DataGridView は使ったことがなかったので、試行錯誤して動作するコードを作ってみました。
    参考になるでしょうか。

     

    と思ったら、KentaroM さんの前のスレッドを見ると、バインドされているようですね。
    # 今回はどうかわかりませんけど。
    その場合は DataGridViewRow を DoDragDrop に渡すのではなく、dataGridView1.Rows[hit.RowIndex].DataBoundItem を渡すと良いかと思います。
    そして dataGridView2_DragDrop の方では、dataGridView2.Rows に追加するのではなく、バインドしているデータソースに追加するようにしてください。

     

    コード ブロック

    private void Form1_Load(object sender, EventArgs e)
    {
        // テストの準備
        // ドロップ元
        dataGridView1.Columns.Add("Col1", "Col1");
        dataGridView1.Columns.Add("Col2", "Col2");
        dataGridView1.Rows.Add("1-1", "1-2");
        dataGridView1.Rows.Add("2-1", "2-2");
        dataGridView1.Rows.Add("3-1", "3-2");
        // ドロップ先
        dataGridView2.Columns.Add("Col1", "Col1");
        dataGridView2.Columns.Add("Col2", "Col2");
        dataGridView2.Rows.Add("A-1", "A-2");
        dataGridView2.AllowDrop = true;
    }

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

        // 念のため、有効なセル上でのみ許可する
        if (hit.Type == DataGridViewHitTestType.Cell
            && (dataGridView1.NewRowIndex == -1
                || dataGridView1.NewRowIndex != hit.RowIndex))
        {
            dataGridView1.DoDragDrop(
                dataGridView1.Rows[hit.RowIndex], DragDropEffects.Copy);
        }
    }

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

    private void dataGridView2_DragDrop(object sender, DragEventArgs e)
    {
        Point clientPoint = dataGridView2.PointToClient(new Point(e.X, e.Y));
        DataGridView.HitTestInfo hit =
            dataGridView2.HitTest(clientPoint.X, clientPoint.Y);

        // ドロップするデータ
        DataGridViewRow dgvr =
            (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
        object[] cellData = new object[dgvr.Cells.Count];
        for (int col = 0; col < dgvr.Cells.Count; col++)
            cellData[col] = dgvr.Cells[col].Value;

        // 追加
        if (hit.RowIndex != -1)
            dataGridView2.Rows.Insert(hit.RowIndex, cellData);
        else
            dataGridView2.Rows.Add(cellData);

        // 移動とのことなので、元のグリッドから削除
        dgvr.DataGridView.Rows.Remove(dgvr);
    }

     

     

    2008年1月9日 12:15

すべての返信

  • 書かれたコードですが、dataGridView3.Rows[hit.RowIndex] と dataGridView3.Rows.GetType() は型が違うのでマズイです。
    それと、Insert や Add メソッドに、他のグリッドの DataGridViewRow を渡すのもダメそうです。

     

    非バインドの DataGridView は使ったことがなかったので、試行錯誤して動作するコードを作ってみました。
    参考になるでしょうか。

     

    と思ったら、KentaroM さんの前のスレッドを見ると、バインドされているようですね。
    # 今回はどうかわかりませんけど。
    その場合は DataGridViewRow を DoDragDrop に渡すのではなく、dataGridView1.Rows[hit.RowIndex].DataBoundItem を渡すと良いかと思います。
    そして dataGridView2_DragDrop の方では、dataGridView2.Rows に追加するのではなく、バインドしているデータソースに追加するようにしてください。

     

    コード ブロック

    private void Form1_Load(object sender, EventArgs e)
    {
        // テストの準備
        // ドロップ元
        dataGridView1.Columns.Add("Col1", "Col1");
        dataGridView1.Columns.Add("Col2", "Col2");
        dataGridView1.Rows.Add("1-1", "1-2");
        dataGridView1.Rows.Add("2-1", "2-2");
        dataGridView1.Rows.Add("3-1", "3-2");
        // ドロップ先
        dataGridView2.Columns.Add("Col1", "Col1");
        dataGridView2.Columns.Add("Col2", "Col2");
        dataGridView2.Rows.Add("A-1", "A-2");
        dataGridView2.AllowDrop = true;
    }

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

        // 念のため、有効なセル上でのみ許可する
        if (hit.Type == DataGridViewHitTestType.Cell
            && (dataGridView1.NewRowIndex == -1
                || dataGridView1.NewRowIndex != hit.RowIndex))
        {
            dataGridView1.DoDragDrop(
                dataGridView1.Rows[hit.RowIndex], DragDropEffects.Copy);
        }
    }

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

    private void dataGridView2_DragDrop(object sender, DragEventArgs e)
    {
        Point clientPoint = dataGridView2.PointToClient(new Point(e.X, e.Y));
        DataGridView.HitTestInfo hit =
            dataGridView2.HitTest(clientPoint.X, clientPoint.Y);

        // ドロップするデータ
        DataGridViewRow dgvr =
            (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
        object[] cellData = new object[dgvr.Cells.Count];
        for (int col = 0; col < dgvr.Cells.Count; col++)
            cellData[col] = dgvr.Cells[col].Value;

        // 追加
        if (hit.RowIndex != -1)
            dataGridView2.Rows.Insert(hit.RowIndex, cellData);
        else
            dataGridView2.Rows.Add(cellData);

        // 移動とのことなので、元のグリッドから削除
        dgvr.DataGridView.Rows.Remove(dgvr);
    }

     

     

    2008年1月9日 12:15
  • アドバイスありがとうございました。

    お蔭様で悪戦苦闘していた事が出来る様になってうれしいです!

    上記していただいたコードをヒントに自分のコードを作りました。

     

    private void dataGridView4_DragDrop(object sender, DragEventArgs e)
            {
                Point clientPoint = dataGridView3.PointToClient(new Point(e.X, e.Y));
                DataGridView.HitTestInfo hit = dataGridView3.HitTest(clientPoint.X, clientPoint.Y);
                DataGridViewRow dgvr = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
                object[] celldata = new object[dgvr.Cells.Count];
                for (int col = 0; col < dgvr.Cells.Count; col++)
                {
                    celldata[col] = dgvr.Cells[col].Value;
                }
                DataRow row = dtable.NewRow();
                row.ItemArray = celldata;
                dtable.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop);
                dgvr.DataGridView.Rows.Remove(dgvr);

        }

     

    で、無事にdrop出来ました。

    今回勉強になった事は、ドラッグされてきたデータをdataGridView4のdataTableに追加する事です。

    dataGridView4に追加するという考え方ではなくて。

    今までドロップ出来なかった原因はPage_Loadイベントで、dataGridView4.DataSource = dataTable2;

    としていたのに、言わば強引にdataGridView4にinsertしようとしていたためにうまくいかなかったんですね。

    オブジェクト指向をもっと頭に叩き込まないといけないですね。勉強になりました。

     

    ありがとうございました!

     

    2008年1月10日 8:07
  • こんにちは。中川俊輔 です。

     

    TH01さん、有用なサンプルコードを作成、回答していただき、ありがとうございます。

     

    KentaroMさんへ

    参考になる返信をしていただき、ありがとうございます。

    問題が解決されたようなので、TH01さんの回答へ回答済みチェックをつけさせていただきました。

     

    回答済みチェックが付くことにより、有用な情報を探している方が情報を見つけやすくなります。
    問題解決につながる回答があった場合は、なるべく回答済みボタンを押してチェックを付けてください。

     

    KentaroMさんはチェックを解除することもできますので、ご確認ください。

     

    それでは!

     

    2008年1月15日 8:00