none
DataGridViewのCellPaintingイベントでヘッダーの結合 RRS feed

  • 質問

  • VisualStudio 2008 Pro

    C# .Netframework 3.5

    グリッドの項目数が多く、見やすくするために関連する列のヘッダーを結合しています。

    CellPaintingイベントでヘッダーの場合に独自で描画させているのですが、結合しない列とデザインが合いません。セルの枠(ふち)に影?が立体的になりません。どのような実装を行えばよいのかわからずご質問させて頂きました。

    どうしていいかわからず途方に暮れています…。なにかヒントでもよいのでご回答お願い致します。

    現状のソースは以下の通りです。

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

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

            }

            /// <summary>
            /// グリッド描画時に指定したヘッダーを結合する
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            /// <param name="columns"></param>
            /// <param name="headerText"></param>
            private void JoinGridHeader(object sender, DataGridViewCellPaintingEventArgs e, List<DataGridViewColumn> columns, string headerText)
            {
                //指定した列を結合する
                // セルの矩形を取得
                Rectangle rect = e.CellBounds;
                //rect.X += 1;
                //rect.Y += 1;
                rect.Height -= 1;
               
                DataGridView dgv = (DataGridView)sender;

                rect.Width = 0;

                // 結合する列の幅を取得して、足す
                foreach (DataGridViewColumn col in columns)
                {
                    rect.Width += col.Width;

                    if (e.ColumnIndex > col.Index)
                    {
                        // 矩形の位置を補正
                        rect.X -= col.Width;
                    }
                }

                // 背景、枠線、セルの値を描画
                using (SolidBrush brush = new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.BackColor))
                using (Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor))
                using (Pen pen = new Pen(dgv.GridColor))
                {               
                    // Erase the cell.
                    e.Graphics.FillRectangle(brush, e.CellBounds);

                    // 背景の描画
                    e.Graphics.FillRectangle(brush, rect);

                    // 枠線の描画
                    e.Graphics.DrawRectangle(pen, rect);

                    //// Draw the grid lines (only the right and bottom lines;
                    //// DataGridView takes care of the others).
                    //e.Graphics.DrawLine(pen, e.CellBounds.Left,
                    //    e.CellBounds.Bottom - 1, e.CellBounds.Right - 1,
                    //    e.CellBounds.Bottom - 1);
                    //e.Graphics.DrawLine(pen, e.CellBounds.Right - 1,
                    //    e.CellBounds.Top, e.CellBounds.Right - 1,
                    //    e.CellBounds.Bottom);

                }

                // セルに表示するテキストを描画
                TextRenderer.DrawText(e.Graphics,
                                headerText,
                                e.CellStyle.Font,
                                rect,
                                e.CellStyle.ForeColor,
                                TextFormatFlags.HorizontalCenter
                                | TextFormatFlags.VerticalCenter);
            }

            private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
            {

                // ガード句
                if (e.RowIndex > -1)
                {
                    // ヘッダー以外は処理なし
                    return;
                }

                if (e.ColumnIndex == this.dataColumn2DataGridViewTextBoxColumn.Index
                    || e.ColumnIndex == this.dataColumn3DataGridViewTextBoxColumn.Index)
                {
                    //カラム2, 3を結合する
                    List<DataGridViewColumn> columns = new List<DataGridViewColumn>();
                    columns.Add(this.dataColumn2DataGridViewTextBoxColumn);
                    columns.Add(this.dataColumn3DataGridViewTextBoxColumn);
                    this.JoinGridHeader(sender, e, columns, "結合1");
                   
                }
                else
                {
                    // 結合セル以外は既定の描画を行う
                    e.Paint(e.ClipBounds, e.PaintParts);
                }

                // イベントハンドラ内で処理を行ったことを通知
                e.Handled = true;
            }

            private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
            {

                this.dataGridView1.Invalidate();
            }
        }
    }


    • 編集済み katsu713b 2014年2月14日 6:13
    2014年2月14日 6:06

回答

  • 境界線が問題になっているのでしょうか? であれば、境界線はいろいろなスタイルがあるので自分で描かない方が良い気がします。AdvancedBorderStyleで上下左右の境界線を個別に無しにすることなどができますので、これを利用されるとうまく行くかもしれません。

    (参考)
    DataGridViewコントロールの連続する同じ値のセルを1つにまとめるには?[2.0のみ、C#、VB]
    http://www.atmarkit.co.jp/fdotnet/dotnettips/593dgvgroupedcell/dgvgroupedcell.html


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク katsu713b 2014年2月18日 0:30
    2014年2月17日 5:14
    モデレータ

すべての返信

  • 境界線が問題になっているのでしょうか? であれば、境界線はいろいろなスタイルがあるので自分で描かない方が良い気がします。AdvancedBorderStyleで上下左右の境界線を個別に無しにすることなどができますので、これを利用されるとうまく行くかもしれません。

    (参考)
    DataGridViewコントロールの連続する同じ値のセルを1つにまとめるには?[2.0のみ、C#、VB]
    http://www.atmarkit.co.jp/fdotnet/dotnettips/593dgvgroupedcell/dgvgroupedcell.html


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク katsu713b 2014年2月18日 0:30
    2014年2月17日 5:14
    モデレータ
  • ご回答ありがとうございます。

    「境界線を表示しない」というのは盲点でした。

    AdvancedBorderStyle=noneで一応うまくいきましたのでこの方法で実装することに致しました。

    とても助かりました。ありがとうございました。

    2014年2月18日 0:30