4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C# DataGridViewの見た目をExcelのようにする

Last updated at Posted at 2023-10-15

はじめに

DataGridViewのCellPaintingの勉強のためにDataGridViewの見た目をExcelっぽくしてみました。あくまで勉強用であり、実用向きではないです。動作も重いです。

datagridview_excel.gif

初期設定

まずはExcelっぽくする前に初期設定をします。

//フォームいっぱいに表示
dataGridView1.Dock = DockStyle.Fill;

//行数と列数
dataGridView1.RowCount = 1000;
dataGridView1.ColumnCount = 100;

//列幅設定
foreach (DataGridViewColumn column in dataGridView1.Columns) { column.Width = 70; };

//列ヘッダースタイル
dataGridView1.EnableHeadersVisualStyles = false;
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;//列ヘッダーの高さ固定
dataGridView1.ColumnHeadersHeight = 26;

//セル値を入力(VirtualMode有効)
dataGridView1.VirtualMode = true;
dataGridView1.CellValueNeeded += (sender, e) => { e.Value = "R" + (e.RowIndex + 1).ToString() + "C" + (e.ColumnIndex + 1).ToString(); };

//ちらつき防止(ダブルバッファリング有効)
typeof(DataGridView).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(dataGridView1, true, null);

CellPaintingを使用せずに通常のコードでできる範囲でExcelっぽくします。

//枠線の色を薄グレーに変更
dataGridView1.GridColor = Color.FromArgb(212, 212, 212);

//選択されていないセルの背景色を白、文字色を黒とする。
dataGridView1.DefaultCellStyle.BackColor = Color.White;
dataGridView1.DefaultCellStyle.ForeColor = Color.Black;

//選択されているセルの背景色を薄グレー、文字色を黒とする。
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.FromArgb(198, 198, 198);
dataGridView1.DefaultCellStyle.SelectionForeColor = Color.Black;

//フォントにシステムフォントを設定
dataGridView1.DefaultCellStyle.Font = SystemInformation.MenuFont;

CellPaintingで見た目を変更する

CellPaintingについて

CellPaintingはセルが描画されなければならないときに発生するイベントです。第2引数のDataGridViewCellPaintingEventArgsのプロパティ値により処理を変更することで、条件により描画内容を変更することができます。

プロパティ 内容
CellBounds Rectangle セルの境界
ClipBounds Rectangle 再描画が必要な領域
ColumnIndex Int32 セルの列インデックス
Graphics Graphics セルの描画に使用されるGraphics
Handled Boolean イベント ハンドラーがイベントを完全に処理したかどうか
PaintParts DataGridViewPaintParts 描画されるセル部分
RowIndex Int32 セルの行インデックス
State DataGridViewElementStates セルの状態

例えば、セルとヘッダーで処理を変更する場合は以下のようになります。

//ヘッダーの場合はインデックスが-1になる
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex >= 0 && e.RowIndex >= 0)//セル
    {
        //セル用の処理
    }
    else if (e.RowIndex < 0 && e.ColumnIndex >= 0)//列ヘッダー
    {
        //列ヘッダー用の処理
    }
    else if (e.ColumnIndex < 0 && e.RowIndex >= 0)//行ヘッダー
    {
        //行ヘッダー用の処理
    }
}

事前準備

CellPaintingのコードを実装する前に、CellPainting内で利用する関数などを作成します。

列番号をアルファベットに変換する

Excelの場合、列ヘッダーにはアルファベットが表示されるので、列番号からアルファベットを求める関数を作成します。

private string ColumnIndex2HeaderString(int index)
{
    int amari;
    string s = "";

    if (index < 0) return "";

    for (int i = 0; i <= 100; i++)
    {
        amari = index % 26;
        s = Convert.ToChar(amari + 65).ToString() + s;
        index = (index - amari) / 26;

        if (index == 0)
        {
            break;
        }
        else
        {
            index -= 1;
        }
    }

    return s;
}

選択範囲の行番号、列番号を取得する

Excelの場合、選択されている行や列のヘッダーが強調表示されるので、現在選択されている行番号と列番号を配列として確保する関数を作成します。

private (HashSet<int> RowIndexs, HashSet<int> ColumnIndexs) getSelectionIndexs()
{
    HashSet<int> row = new HashSet<int>();
    HashSet<int> column = new HashSet<int>();

    foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
    {
        row.Add(cell.RowIndex);
        column.Add(cell.ColumnIndex);
    }

    return (row, column);
}

選択範囲の最初のセルを取得する

Excelの場合、選択範囲の最初のセルだけは、薄グレーでなく白のままとなります。選択範囲が変更された場合、SelectionChangedイベントを利用して選択範囲の最初のセルの行列番号を確保します。

//選択範囲の最初のセル
int SelectionStartRowIndex = 0;
int SelectionStartColumnIndex = 0;

//セル範囲変更時
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    //選択範囲の最初のセルの行番号、列番号をストック
    bool isFirstCell = true;
    var cell = dataGridView1.CurrentCell;

    //上のセルが選択されていない
    if (isFirstCell)
    {
        isFirstCell = cell.RowIndex == 0 || (0 <= cell.RowIndex - 1 && !dataGridView1[cell.ColumnIndex, cell.RowIndex - 1].Selected);
    }
    //下のセルが選択されていない
    if (isFirstCell)
    {
        isFirstCell = cell.RowIndex == dataGridView1.RowCount - 1 || (cell.RowIndex + 1 < dataGridView1.RowCount && !dataGridView1[cell.ColumnIndex, cell.RowIndex + 1].Selected);
    }
    //左のセルが選択されていない
    if (isFirstCell)
    {
        isFirstCell = cell.ColumnIndex == 0 || (0 <= cell.ColumnIndex - 1 && !dataGridView1[cell.ColumnIndex - 1, cell.RowIndex].Selected);
    }
    //右のセルが選択されていない
    if (isFirstCell)
    {
        isFirstCell = cell.ColumnIndex == dataGridView1.ColumnCount - 1 || (cell.ColumnIndex + 1 < dataGridView1.ColumnCount && !dataGridView1[cell.ColumnIndex + 1, cell.RowIndex].Selected);
    }

    //左右上下いずれも選択状態にない場合は選択範囲の最初のセルとみなす
    if (isFirstCell)
    {
        SelectionStartRowIndex = dataGridView1.CurrentCell.RowIndex;
        SelectionStartColumnIndex = dataGridView1.CurrentCell.ColumnIndex;
    }
}

CellPaintingを実装する

大枠を実装する

処理としては、

  • セルの場合:選択範囲の最初のセルかそうでないかで処理を分ける。また選択範囲かどうかで処理を分ける。
  • 列ヘッダーの場合:選択されているかどうかで処理を分ける。列番号(アルファベット)を描画する。
  • 行ヘッダーの場合:選択されているかどうかで処理を分ける。行番号を描画する。

となります。

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    //選択範囲を取得
    var SelectionIndexs = getSelectionIndexs();

    if (e.ColumnIndex >= 0 && e.RowIndex >= 0)//セルの処理
    {
        //選択範囲の最初のセルかどうか
        if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected
            && SelectionStartRowIndex == e.RowIndex && SelectionStartColumnIndex == e.ColumnIndex)
        {
            //選択範囲の最初のセルの場合の処理
        }
        else
        {
            //選択範囲の最初のセル以外の処理
        }

        if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)//選択範囲の場合
        {
            //選択範囲の場合の処理
        }
        else//選択範囲以外
        {
            //選択範囲以外の場合の処理
        }

        //処理完了
        e.Handled = true;
    }
    else if (e.RowIndex < 0 && e.ColumnIndex >= 0)//列ヘッダーの処理
    {
        //選択されているかどうか
        if (SelectionIndexs.ColumnIndexs.Contains(e.ColumnIndex))
        {
            //選択されている列の場合の処理
        }

        //その他の処理

        //列番号描画処理

        //処理完了
        e.Handled = true;
    }
    else if (e.ColumnIndex < 0 && e.RowIndex >= 0)//行ヘッダーの処理
    {
        //選択されているかどうか
        if (SelectionIndexs.RowIndexs.Contains(e.RowIndex))
        {
            //選択されている列の場合の処理
        }

        //その他の処理

        //行番号描画処理

        //処理完了
        e.Handled = true;
    }
}

実際に実装する

具体的な実装をするにあたり、以下を参考にさせていただきました。

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    //枠描画用
    Pen pen_border = new Pen(new SolidBrush(Color.FromArgb(33, 115, 70)));

    //選択範囲
    var SelectionIndexs = getSelectionIndexs();

    if (e.ColumnIndex >= 0 && e.RowIndex >= 0)//セル
    {
        //選択範囲の最初のセルの場合は背景を除き、通常通り描画
        if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected
            && SelectionStartRowIndex == e.RowIndex && SelectionStartColumnIndex == e.ColumnIndex)
        {
            DataGridViewPaintParts paintParts = e.PaintParts & ~DataGridViewPaintParts.SelectionBackground;
            e.Paint(e.ClipBounds, paintParts);
        }
        else
        {
            e.Paint(e.ClipBounds, e.PaintParts);
        }

        //追加描画
        if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)//選択範囲の場合
        {
            //選択範囲の右の線
            if ((e.ColumnIndex + 1 < dataGridView1.ColumnCount && !dataGridView1[e.ColumnIndex + 1, e.RowIndex].Selected)
                || e.ColumnIndex == dataGridView1.ColumnCount - 1)
            {
                int x = e.CellBounds.X + e.CellBounds.Width - 1;
                e.Graphics.DrawLine(pen_border, x, e.CellBounds.Y, x, e.CellBounds.Y + e.CellBounds.Height - 1);
            }

            //選択範囲の下の線
            if ((e.RowIndex + 1 < dataGridView1.RowCount && !dataGridView1[e.ColumnIndex, e.RowIndex + 1].Selected)
                || e.RowIndex == dataGridView1.RowCount - 1)
            {
                int y = e.CellBounds.Y + e.CellBounds.Height - 1;
                e.Graphics.DrawLine(pen_border, e.CellBounds.X, y, e.CellBounds.X + e.CellBounds.Width - 1, y);
            }
        }
        else//選択範囲以外
        {
            if (e.ColumnIndex + 1 < dataGridView1.ColumnCount && dataGridView1[e.ColumnIndex + 1, e.RowIndex].Selected)//選択範囲の左に隣接しているセル
            {
                e.Graphics.DrawRectangle(pen_border, e.CellBounds.X + e.CellBounds.Width - 2, e.CellBounds.Y, 1, e.CellBounds.Height - 1);
            }
            if (0 <= e.ColumnIndex - 1 && dataGridView1[e.ColumnIndex - 1, e.RowIndex].Selected)//選択範囲の右に隣接しているセル
            {
                e.Graphics.DrawRectangle(pen_border, e.CellBounds.X - 1, e.CellBounds.Y, 1, e.CellBounds.Height - 1);
            }
            if (e.RowIndex + 1 < dataGridView1.RowCount && dataGridView1[e.ColumnIndex, e.RowIndex + 1].Selected)//選択範囲の上に隣接しているセル
            {
                e.Graphics.DrawRectangle(pen_border, e.CellBounds.X, e.CellBounds.Y + e.CellBounds.Height - 2, e.CellBounds.Width - 1, 1);
            }
            if (0 <= e.RowIndex - 1 && dataGridView1[e.ColumnIndex, e.RowIndex - 1].Selected)//選択範囲の下に隣接しているセル
            {
                e.Graphics.DrawRectangle(pen_border, e.CellBounds.X, e.CellBounds.Y - 1, e.CellBounds.Width - 1, 1);
            }
        }
        e.Handled = true;
    }
    else if (e.RowIndex < 0 && e.ColumnIndex >= 0)//列ヘッダー
    {
        //通常通り描画
        e.Paint(e.ClipBounds, e.PaintParts);

        //選択されている列であれば
        bool selected = false;
        if (SelectionIndexs.ColumnIndexs.Contains(e.ColumnIndex))
        {
            selected = true;

            //強調ラインを引く
            Rectangle rect = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, dataGridView1.FirstDisplayedScrollingRowIndex, true);
            e.Graphics.DrawRectangle(pen_border, rect.X, dataGridView1.ColumnHeadersHeight - 1, rect.Width - 1, 1);
        }

        //選択有無で背景色を変更
        dataGridView1.Columns[e.ColumnIndex].HeaderCell.Style.BackColor = selected ? Color.FromArgb(210, 210, 210) : Color.FromArgb(230, 230, 230);

        //列番号描画
        Rectangle indexRect = e.CellBounds;
        indexRect.Inflate(-2, -2);
        TextRenderer.DrawText(
            e.Graphics,
            ColumnIndex2HeaderString(e.ColumnIndex),
            new Font(SystemInformation.MenuFont.FontFamily, 10F, FontStyle.Regular),
            indexRect,
            selected ? Color.FromArgb(27, 93, 57) : Color.Black,
            TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);

        e.Handled = true;
    }
    else if (e.ColumnIndex < 0 && e.RowIndex >= 0)//行ヘッダー
    {
        //通常通り描画
        e.Paint(e.ClipBounds, e.PaintParts);

        //選択されている行であれば
        bool selected = false;
        if (SelectionIndexs.RowIndexs.Contains(e.RowIndex))
        {
            selected = true;

            //強調ラインを引く
            Rectangle rect = dataGridView1.GetCellDisplayRectangle(dataGridView1.FirstDisplayedScrollingColumnIndex, e.RowIndex, true);
            e.Graphics.DrawRectangle(pen_border, dataGridView1.RowHeadersWidth - 1, rect.Y, 1, rect.Height - 1);
        }

        //選択有無で背景色を変更
        dataGridView1.Rows[e.RowIndex].HeaderCell.Style.BackColor = selected ? Color.FromArgb(210, 210, 210) : Color.FromArgb(230, 230, 230);

        //行番号描画
        Rectangle indexRect = e.CellBounds;
        indexRect.Inflate(-2, -2);
        TextRenderer.DrawText(
            e.Graphics,
            (e.RowIndex + 1).ToString(),
            new Font(SystemInformation.MenuFont.FontFamily, 10F, FontStyle.Regular),
            indexRect,
            selected ? Color.FromArgb(27, 93, 57) : Color.Black,
            TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);

        e.Handled = true;
    }
}

実装コード

実装コードの全てです。Form上にDataGridViewを1個配置しています(dataGridView1)。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //フォームいっぱいに表示
            dataGridView1.Dock = DockStyle.Fill;

            //行数と列数
            dataGridView1.RowCount = 1000;
            dataGridView1.ColumnCount = 100;

            //列幅設定
            foreach (DataGridViewColumn column in dataGridView1.Columns) { column.Width = 70; };

            //列ヘッダースタイル
            dataGridView1.EnableHeadersVisualStyles = false;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;//列ヘッダーの高さ固定
            dataGridView1.ColumnHeadersHeight = 26;

            //セル値を入力(VirtualMode有効)
            dataGridView1.VirtualMode = true;
            dataGridView1.CellValueNeeded += (sender, e) => { e.Value = "R" + (e.RowIndex + 1).ToString() + "C" + (e.ColumnIndex + 1).ToString(); };

            //ちらつき防止(ダブルバッファリング有効)
            typeof(DataGridView).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(dataGridView1, true, null);

            //枠線の色を薄グレーに変更
            dataGridView1.GridColor = Color.FromArgb(212, 212, 212);

            //選択されていないセルの背景色を白、文字色を黒とする。
            dataGridView1.DefaultCellStyle.BackColor = Color.White;
            dataGridView1.DefaultCellStyle.ForeColor = Color.Black;

            //選択されているセルの背景色を薄グレー、文字色を黒とする。
            dataGridView1.DefaultCellStyle.SelectionBackColor = Color.FromArgb(198, 198, 198);
            dataGridView1.DefaultCellStyle.SelectionForeColor = Color.Black;

            //フォントにシステムフォントを設定
            dataGridView1.DefaultCellStyle.Font = SystemInformation.MenuFont;

            //描画を通常のものから変更
            dataGridView1.CellPainting += (sender, e) => { dataGridView1_CellPainting(sender, e); };

            //選択範囲変更時
            dataGridView1.SelectionChanged += (sender, e) => { dataGridView1_SelectionChanged(sender, e); };
        }

        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            //枠描画用
            Pen pen_border = new Pen(new SolidBrush(Color.FromArgb(33, 115, 70)));

            //選択範囲
            var SelectionIndexs = getSelectionIndexs();

            if (e.ColumnIndex >= 0 && e.RowIndex >= 0)//セル
            {
                //選択範囲の最初のセルの場合は背景を除き、通常通り描画
                if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected
                    && SelectionStartRowIndex == e.RowIndex && SelectionStartColumnIndex == e.ColumnIndex)
                {
                    DataGridViewPaintParts paintParts = e.PaintParts & ~DataGridViewPaintParts.SelectionBackground;
                    e.Paint(e.ClipBounds, paintParts);
                }
                else
                {
                    e.Paint(e.ClipBounds, e.PaintParts);
                }

                //追加描画
                if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)//選択範囲の場合
                {
                    //選択範囲の右の線
                    if ((e.ColumnIndex + 1 < dataGridView1.ColumnCount && !dataGridView1[e.ColumnIndex + 1, e.RowIndex].Selected)
                        || e.ColumnIndex == dataGridView1.ColumnCount - 1)
                    {
                        int x = e.CellBounds.X + e.CellBounds.Width - 1;
                        e.Graphics.DrawLine(pen_border, x, e.CellBounds.Y, x, e.CellBounds.Y + e.CellBounds.Height - 1);
                    }

                    //選択範囲の下の線
                    if ((e.RowIndex + 1 < dataGridView1.RowCount && !dataGridView1[e.ColumnIndex, e.RowIndex + 1].Selected)
                        || e.RowIndex == dataGridView1.RowCount - 1)
                    {
                        int y = e.CellBounds.Y + e.CellBounds.Height - 1;
                        e.Graphics.DrawLine(pen_border, e.CellBounds.X, y, e.CellBounds.X + e.CellBounds.Width - 1, y);
                    }
                }
                else//選択範囲以外
                {
                    if (e.ColumnIndex + 1 < dataGridView1.ColumnCount && dataGridView1[e.ColumnIndex + 1, e.RowIndex].Selected)//選択範囲の左に隣接しているセル
                    {
                        e.Graphics.DrawRectangle(pen_border, e.CellBounds.X + e.CellBounds.Width - 2, e.CellBounds.Y, 1, e.CellBounds.Height - 1);
                    }
                    if (0 <= e.ColumnIndex - 1 && dataGridView1[e.ColumnIndex - 1, e.RowIndex].Selected)//選択範囲の右に隣接しているセル
                    {
                        e.Graphics.DrawRectangle(pen_border, e.CellBounds.X - 1, e.CellBounds.Y, 1, e.CellBounds.Height - 1);
                    }
                    if (e.RowIndex + 1 < dataGridView1.RowCount && dataGridView1[e.ColumnIndex, e.RowIndex + 1].Selected)//選択範囲の上に隣接しているセル
                    {
                        e.Graphics.DrawRectangle(pen_border, e.CellBounds.X, e.CellBounds.Y + e.CellBounds.Height - 2, e.CellBounds.Width - 1, 1);
                    }
                    if (0 <= e.RowIndex - 1 && dataGridView1[e.ColumnIndex, e.RowIndex - 1].Selected)//選択範囲の下に隣接しているセル
                    {
                        e.Graphics.DrawRectangle(pen_border, e.CellBounds.X, e.CellBounds.Y - 1, e.CellBounds.Width - 1, 1);
                    }
                }
                e.Handled = true;
            }
            else if (e.RowIndex < 0 && e.ColumnIndex >= 0)//列ヘッダー
            {
                //通常通り描画
                e.Paint(e.ClipBounds, e.PaintParts);

                //選択されている列であれば
                bool selected = false;
                if (SelectionIndexs.ColumnIndexs.Contains(e.ColumnIndex))
                {
                    selected = true;

                    //強調ラインを引く
                    Rectangle rect = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, dataGridView1.FirstDisplayedScrollingRowIndex, true);
                    e.Graphics.DrawRectangle(pen_border, rect.X, dataGridView1.ColumnHeadersHeight - 1, rect.Width - 1, 1);
                }

                //選択有無で背景色を変更
                dataGridView1.Columns[e.ColumnIndex].HeaderCell.Style.BackColor = selected ? Color.FromArgb(210, 210, 210) : Color.FromArgb(230, 230, 230);

                //列番号描画
                Rectangle indexRect = e.CellBounds;
                indexRect.Inflate(-2, -2);
                TextRenderer.DrawText(
                    e.Graphics,
                    ColumnIndex2HeaderString(e.ColumnIndex),
                    new Font(SystemInformation.MenuFont.FontFamily, 10F, FontStyle.Regular),
                    indexRect,
                    selected ? Color.FromArgb(27, 93, 57) : Color.Black,
                    TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);

                e.Handled = true;
            }
            else if (e.ColumnIndex < 0 && e.RowIndex >= 0)//行ヘッダー
            {
                //通常通り描画
                e.Paint(e.ClipBounds, e.PaintParts);

                //選択されている行であれば
                bool selected = false;
                if (SelectionIndexs.RowIndexs.Contains(e.RowIndex))
                {
                    selected = true;

                    //強調ラインを引く
                    Rectangle rect = dataGridView1.GetCellDisplayRectangle(dataGridView1.FirstDisplayedScrollingColumnIndex, e.RowIndex, true);
                    e.Graphics.DrawRectangle(pen_border, dataGridView1.RowHeadersWidth - 1, rect.Y, 1, rect.Height - 1);
                }

                //選択有無で背景色を変更
                dataGridView1.Rows[e.RowIndex].HeaderCell.Style.BackColor = selected ? Color.FromArgb(210, 210, 210) : Color.FromArgb(230, 230, 230);

                //行番号描画
                Rectangle indexRect = e.CellBounds;
                indexRect.Inflate(-2, -2);
                TextRenderer.DrawText(
                    e.Graphics,
                    (e.RowIndex + 1).ToString(),
                    new Font(SystemInformation.MenuFont.FontFamily, 10F, FontStyle.Regular),
                    indexRect,
                    selected ? Color.FromArgb(27, 93, 57) : Color.Black,
                    TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);

                e.Handled = true;
            }
        }

        //列番号→列アルファベット
        private string ColumnIndex2HeaderString(int index)
        {
            int amari;
            string s = "";

            if (index < 0) return "";

            for (int i = 0; i <= 100; i++)
            {
                amari = index % 26;
                s = Convert.ToChar(amari + 65).ToString() + s;
                index = (index - amari) / 26;

                if (index == 0)
                {
                    break;
                }
                else
                {
                    index -= 1;
                }
            }

            return s;
        }

        //選択されている行、列番号の配列
        private (HashSet<int> RowIndexs, HashSet<int> ColumnIndexs) getSelectionIndexs()
        {
            HashSet<int> row = new HashSet<int>();
            HashSet<int> column = new HashSet<int>();

            foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
            {
                row.Add(cell.RowIndex);
                column.Add(cell.ColumnIndex);
            }

            return (row, column);
        }

        //選択範囲の最初のセル
        int SelectionStartRowIndex = 0;
        int SelectionStartColumnIndex = 0;

        //セル範囲変更時
        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            //選択範囲の最初のセルの行番号、列番号をストック
            bool isFirstCell = true;
            var cell = dataGridView1.CurrentCell;

            //上のセルが選択されていない
            if (isFirstCell)
            {
                isFirstCell = cell.RowIndex == 0 || (0 <= cell.RowIndex - 1 && !dataGridView1[cell.ColumnIndex, cell.RowIndex - 1].Selected);
            }
            //下のセルが選択されていない
            if (isFirstCell)
            {
                isFirstCell = cell.RowIndex == dataGridView1.RowCount - 1 || (cell.RowIndex + 1 < dataGridView1.RowCount && !dataGridView1[cell.ColumnIndex, cell.RowIndex + 1].Selected);
            }
            //左のセルが選択されていない
            if (isFirstCell)
            {
                isFirstCell = cell.ColumnIndex == 0 || (0 <= cell.ColumnIndex - 1 && !dataGridView1[cell.ColumnIndex - 1, cell.RowIndex].Selected);
            }
            //右のセルが選択されていない
            if (isFirstCell)
            {
                isFirstCell = cell.ColumnIndex == dataGridView1.ColumnCount - 1 || (cell.ColumnIndex + 1 < dataGridView1.ColumnCount && !dataGridView1[cell.ColumnIndex + 1, cell.RowIndex].Selected);
            }

            //左右上下いずれも選択状態にない場合は選択範囲の最初のセルとみなす
            if (isFirstCell)
            {
                SelectionStartRowIndex = dataGridView1.CurrentCell.RowIndex;
                SelectionStartColumnIndex = dataGridView1.CurrentCell.ColumnIndex;
            }

            //表示更新
            dataGridView1.Refresh();
        }
    }
}
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?