プログラムを書こう!

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

C#のDataGridViewでセルをドラックアンドドロップでコピーする。

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

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 フォームがロードされた時に呼び出されます。
         * 
         * @param [in] sender フォーム
         * @param [in] e イベント
         */
        private void Form1_Load(object sender, EventArgs e)
        {
            // サンプルデータを設定します。
            // ドロップ元のDataGridView
            dataGridView1.ColumnCount = 3;
            dataGridView1.Columns[0].HeaderText = "値A";
            dataGridView1.Columns[1].HeaderText = "値B";
            dataGridView1.Columns[2].HeaderText = "値C";
            dataGridView1.Rows.Add("A-1", "B-1", "C-1");
            dataGridView1.Rows.Add("A-2", "B-2", "C-2");
            dataGridView1.Rows.Add("A-3", "B-3", "C-3");

            // 選択モードをセルに設定します。
            dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;

            // ドロップ先のDataGridView
            dataGridView2.ColumnCount = 3;
            dataGridView2.Columns[0].HeaderText = "値X";
            dataGridView2.Columns[1].HeaderText = "値Y";
            dataGridView2.Columns[2].HeaderText = "値Z";
            dataGridView2.Rows.Add("X-1", "Y-1", "Z-1");
            dataGridView2.Rows.Add("X-2", "Y-2", "Z-2");
            dataGridView2.Rows.Add("X-3", "Y-3", "Z-3");

            // ドロップを許可します。
            dataGridView2.AllowDrop = true;
        }

        /**
         * @brief マウスのボタンが押下された時に呼び出されます。
         * 
         * @param [in] sender マウスのボタン
         * @param [in] e イベント
         */
        private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
        {
            // マウスの左ボタン以外が押下された場合
            if (e.Button != MouseButtons.Left)
            {
                // 何もしません。
                return;
            }

            // マウスが押下された座標から、dataGridViewの位置情報を取得します。
            var hitTest = dataGridView1.HitTest(e.X, e.Y);
            int rowIndex = hitTest.RowIndex;
            int columnIndex = hitTest.ColumnIndex;

            // ヘッダ列、ヘッダ行の場合
            if ((rowIndex < 0) || (columnIndex < 0))
            {
                // 何もしません。
                return;
            }

            // ドロップ元(dataGridView1)のセルの内容を取得します。
            var text = (string)dataGridView1.Rows[rowIndex].Cells[columnIndex].Value;

            // セルの内容が取得できない場合
            if (text == null)
            {
                // 何もしません。
                return;
            }

            // ドラッグアンドドロップ動作を開始します。
            dataGridView1.DoDragDrop(text, 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)
        {
            // ドロップ先(dataGridView2)のクライアント位置からDataGridViewの位置情報を取得します。
            var value = e.Data.GetData(typeof(string)) as string;
            var point = dataGridView2.PointToClient(new Point(e.X, e.Y));
            var hitTest = dataGridView2.HitTest(point.X, point.Y);
            int columnIndex = hitTest.ColumnIndex;
            int rowIndex = hitTest.RowIndex;

            // ヘッダ列、ヘッダ行ではない場合
            if ((columnIndex != -1) && (rowIndex != -1))
            {
                // ドロップ元(dataGridView1)のセルの内容を、
                // ドロップ先(dataGridView2)のセルにコピーします。
                dataGridView2[columnIndex, rowIndex].Value = value;
            }
        }
    }
}

目次へ

3. おわりに

前回

paveway.hatenablog.com

行の移動を紹介しましたが、今回はセルの内容をコピーしたいという要望もあったので、続けて調査しました。

今のシゴトに飽きちゃった...そんなあなたの見方です!【IT派遣テクノウェイブ】

作って覚えるVisual C# 2017 デスクトップアプリ入門

作って覚えるVisual C# 2017 デスクトップアプリ入門

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

目次へ


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

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

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

目次へ