プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

C#のDataGridViewで行をドラックアンドドロップする。

この記事は2019年04月19日に投稿しました。

f:id:paveway:20190914064630j:plain

目次

  1. はじめに
  2. C#のDataGridViewで行をドラックアンドドロップする
  3. おわりに

実戦で役立つ C#プログラミングのイディオム/定石&パターン

実戦で役立つ C#プログラミングのイディオム/定石&パターン

1. はじめに

こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているC#のDataGridViewで行をドラックアンドドロップする方法についてです。

目次へ

2. C#のDataGridViewで行をドラックアンドドロップする

C#のDataGridViewで行をドラックアンドドロップするには以下のような実装になります。

フォームにDataGridViewが2つ配置されている(それぞれdataGridView1, dataGridView2)とします。

実装例

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Sample
{
    public partial class Form1 : Form
    {
        /**
         * @brief コンストラクタ
         */
        public Form1()
        {
            InitializeComponent();
        }

        /**
         * @brief dataGridView1でマウスが移動した時に呼び出されます。
         *
         * @param [in] sender マウス
         * @param [in] e イベント
         */
        private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
        {
            // マウス座標のDataGridViewの位置情報を取得します。
            var hitTest = dataGridView1.HitTest(e.X, e.Y);

            // 念のため、有効なセル上でのみ許可する
            int newRowIndex = dataGridView1.NewRowIndex;
            int rowIndex = hitTest.RowIndex;
            if ((hitTest.Type == DataGridViewHitTestType.Cell)
                && ((newRowIndex == -1) || (newRowIndex != rowIndex)))
            {
                // ドラッグアンドドロップ動作を開始します。
                var row = dataGridView1.Rows[rowIndex];
                dataGridView1.DoDragDrop(row, DragDropEffects.Copy);
            }
        }

        /**
         * @brief ドラッグされた場合呼び出されます。
         * 
         * @param [in] sender 対象のコントロール
         * @parma [in] e イベント
         */
        private void dataGridView2_DragEnter(object sender, DragEventArgs e)
        {
            // ドラッグアンドドロップのドロップ効果をコピーに設定します。
            e.Effect = DragDropEffects.Copy;
        }

        /**
         * @brief ドラッグアンドドロップでドロップされた時に呼び出されます。
         * 
         * @param [in] sender 対象のコントロール
         * @parma [in] e イベント
         */
        private void dataGridView2_DragDrop(object sender, DragEventArgs e)
        {
            // ドロップ元(dataGridView1)のデータを取得します。
            var row = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
            var cellDataNum = row.Cells.Count;
            var cellData = new object[cellDataNum];
            for (int column = 0; column < cellDataNum; ++column)
            {
                cellData[column] = row.Cells[column].Value;
            }

            // ドロップ先(dataGridView2)のクライアント位置からDataGridViewの位置情報を取得します。
            var point = dataGridView2.PointToClient(new Point(e.X, e.Y));
            var hitTest = dataGridView2.HitTest(point.X, point.Y);

            // ドロップ先(dataGridView2)の行位置を取得します。
            int rowIndex = hitTest.RowIndex;

            // ドロップ先(dataGridView2)の行位置がヘッダー行では無い場合
            if (rowIndex != -1)
            {
                // 該当行に挿入します。
                dataGridView2.Rows.Insert(rowIndex, cellData);
            }

            // ドロップ先(dataGridView2)の行位置がヘッダー行の場合
            else
            {
                // 末尾に行を追加します。
                dataGridView2.Rows.Add(cellData);
            }

            // 移動する場合、元のdataGridView1から該当行を削除します。
            // コピーする場合、以下の行はコメントアウトしてください。
            row.DataGridView.Rows.Remove(row);
        }
}

目次へ

3. おわりに

今回の要件で、ある表から別の表に行を移動したいという要望がありました。
そのためDataGridViewで実現可能か調査しました。

GEEK JOB

確かな力が身につくC#「超」入門 (Informatics&IDEA)

確かな力が身につくC#「超」入門 (Informatics&IDEA)

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ