【C#】マウス操作で行を並び替えに対応させる方法【データグリッドビュー】

C#

本日はデータグリッドビュー!
並び順を入れ替える作業をマウス操作(ドラッグ&ドロップ)で行いたいと要望を受けました。

元々データグリッドビュー上にボタンを配置し上下へ移動の動きにしていたものの、
それだと一個ずつずらしてくのが面倒!!との事でお直ししたコードおご紹介。

スポンサーリンク

メンバ変数と事前準備


今回はデータグリッドビューイベントの【MouseDown】【MouseMove】【DragOver】【DragEnter】の4つ追加ですね。
まず初めにデータグリッドビューAllow Drop をTrueにします。

次にメンバ変数として下記を配置。

        private Rectangle dragBoxFromMouseDown;      // 座標用
        private int rowIndexFromMouseDown;           // 移動元Index用
        private int rowIndexOfItemUnderMouseToDrop ; // 移動先Index用

これらを追加したら後は順番にイベントの追加をして行きます。

データグリッドマウス移動処理

 

        /////////////////////////////////////////////////////////
        //  概要:データグリッドマウス移動処理                     
        //  はまみ:2019/10/09                                 
        /////////////////////////////////////////////////////////
        private void DataGridView_MouseMove(object sender, MouseEventArgs e)
        {
            // 左クリックの場合
            if (e.Button == MouseButtons.Left)
            {
                if (dragBoxFromMouseDown != Rectangle.Empty && !(dragBoxFromMouseDown.Contains(e.X, e.Y)))
                {
                    DragDropEffects dropEffect = DataGridView.DoDragDrop(DataGridView.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
                }
            }
        }

データグリッドマウスダウン処理

 

        /////////////////////////////////////////////////////////
        //  概要:データグリッドマウスダウン処理                      
        //  はまみ:2019/10/09                                 
        /////////////////////////////////////////////////////////
        private void DataGridView_MouseDown(object sender, MouseEventArgs e)
        {
            rowIndexFromMouseDown = DataGridView.HitTest(e.X, e.Y).RowIndex;

            // ヘッダー以外
            if (rowIndexFromMouseDown > -1)
            {
                var dragSize = SystemInformation.DragSize;
                // ドラッグ操作が開始されない範囲を取得
                dragBoxFromMouseDown = new Rectangle(new Point(e.X - dragSize.Width / 2, e.Y - dragSize.Height / 2), dragSize);
            }
            else
            {
                dragBoxFromMouseDown = Rectangle.Empty;
            }
        }

データグリッドドラッグオ-バー処理

 

        /////////////////////////////////////////////////////////
        //  概要:データグリッドドラッグオ-バー処理                      
        //  はまみ:2019/10/09                                 
        /////////////////////////////////////////////////////////
        private void DataGridView_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }

データグリッドドロップ処理

 

        /////////////////////////////////////////////////////////
        //  概要:データグリッドドロップ処理                      
        //  はまみ:2019/10/09                                 
        /////////////////////////////////////////////////////////
        private void DataGridView_DragDrop(object sender, DragEventArgs e)
        {
            // データグリッドのポイントを取得
            Point clientPoint = DataGridView.PointToClient(new Point(e.X, e.Y));
            // 移動先INDEX
            rowIndexOfItemUnderMouseToDrop = DataGridView.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

            // ドラッグ&ドロップ効果【移動】の場合・INDEX範囲内の場合
            if (e.Effect == DragDropEffects.Move &&
               rowIndexOfItemUnderMouseToDrop > -1)
            {
                // 移動データ退避
                DataTable Dt = (DataTable)DataGridView.DataSource;
                Object[] rowArray = Dt.Rows[rowIndexFromMouseDown].ItemArray;
                DataRow row = Dt.NewRow();
                row.ItemArray = rowArray;

                // 移動元削除
                Dt.Rows.RemoveAt(rowIndexFromMouseDown);
                // 移動先新規行挿入
                Dt.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop);
            }
        }

★おわりに-実際の完成形動作


上記コードを実装するとこんな動作になります。

実際に実装してみて思いましたが、移動頻度&項目が多い場合等はこっちの方が断然楽。
こういう所にも気配りというか【 気づき 】が出来なきゃまだまだ真のSEには成れませんね。。。
是非お試しください~(ᵔᴥᵔ)

コメント