본문 바로가기

Development/C#

DataGridView의 헤더를 멀티로 만들어보자

이 포스트는 외국 사이트를 기초로 해서 만들었다. 어딘지 기억이 잘 안난다.. 구글링으로 찾아보면 나올것이다.

DataGridView의 헤더는 하나밖에 안된다. 일반 리스트로 보는데는 문제가 없지만 업무용으로 만들다 보면 내용을 그룹핑해야 할 상황이 나오기도 하는데 그럴때 하나로 밖에 안되면 UI를 만드는데 상당히 안좋은 모습이 된다.

이걸 다중으로 그룹핑해서 보여주면 직관적으로 볼 수 있는 점이 있기에 포스트를 해본다.

간단하게 설명하면 약간의 트릭이다. DataGridView의 Paint를 사용해서 그룹핑의 효과를 만들어 내는게 요점이다.

1. 그럼 먼저 다음과 C#의 도구상에서 DataGridView를 하나를 선택한다.


2. DataGridView의 속성중 ColumnHeadersHeightSizeMode를 DisableResizeing으로 설정한다.


3. 헤더의 Height를 현재 보여지고 있는 헤더의 2배 크기로 만든다.

4. ColumnHeadersDefaultCellStyle을 클릭하여 Alignment를 BottomCenter로 설정한다.




5. DataGridView의 이벤트 탭으로 가서 Paint, CellPaint, Scroll, ColumnWidthChanged 이벤트를 추가한다.



5. 해당 이벤트의 소스로 가서 각각 다음과 같이 작성하면 끝난다.

private void dataGridView1_Paint(object sender, PaintEventArgs e)

        {

            DataGridView gv = (DataGridView)sender;

            string[] strHeaders = { "헤더1", "헤더2"};

            StringFormat format = new StringFormat();

            format.Alignment = StringAlignment.Center;

            format.LineAlignment = StringAlignment.Center;


            // Category Painting

            {

                Rectangle r1 = gv.GetCellDisplayRectangle(0, -1, false);

                int width1 = gv.GetCellDisplayRectangle(1, -1, false).Width;

                int width2 = gv.GetCellDisplayRectangle(2, -1, false).Width;


                r1.X += 1;

                r1.Y += 1;

                r1.Width = r1.Width + width1 + width2 - 2;

                r1.Height = (r1.Height / 2) - 2;

                e.Graphics.DrawRectangle(new Pen(gv.BackgroundColor), r1);

                e.Graphics.FillRectangle(new SolidBrush(gv.ColumnHeadersDefaultCellStyle.BackColor),

                    r1);


                e.Graphics.DrawString(strHeaders[0],

                    gv.ColumnHeadersDefaultCellStyle.Font,

                    new SolidBrush(gv.ColumnHeadersDefaultCellStyle.ForeColor),

                    r1,

                    format);

            }


            // Projection Painting

            {

                Rectangle r2 = gv.GetCellDisplayRectangle(3, -1, false);

                int width = gv.GetCellDisplayRectangle(4, -1, false).Width;

                r2.X += 1;

                r2.Y += 1;

                r2.Width = r2.Width + width - 2;

                r2.Height = (r2.Height / 2) - 2;

                e.Graphics.DrawRectangle(new Pen(gv.BackgroundColor), r2);

                e.Graphics.FillRectangle(new SolidBrush(gv.ColumnHeadersDefaultCellStyle.BackColor),

                    r2);


                e.Graphics.DrawString(strHeaders[1],

                    gv.ColumnHeadersDefaultCellStyle.Font,

                    new SolidBrush(gv.ColumnHeadersDefaultCellStyle.ForeColor),

                    r2,

                    format);

            }

        }


        private void dataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)

        {

            DataGridView gv = (DataGridView)sender;

            Rectangle rtHeader = gv.DisplayRectangle;

            rtHeader.Height = gv.ColumnHeadersHeight / 2;

            gv.Invalidate(rtHeader);

        }


        private void dataGridView1_Scroll(object sender, ScrollEventArgs e)

        {

            DataGridView gv = (DataGridView)sender;

            Rectangle rtHeader = gv.DisplayRectangle;

            rtHeader.Height = gv.ColumnHeadersHeight / 2;

            gv.Invalidate(rtHeader);

        }


        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)

        {

            if (e.RowIndex == -1 && e.ColumnIndex > -1)

            {

                Rectangle r = e.CellBounds;

                r.Y += e.CellBounds.Height / 2;

                r.Height = e.CellBounds.Height / 2;


                e.PaintBackground(r, true);


                e.PaintContent(r);

                e.Handled = true;

            }

        }


6. 프로그램을 실행하면 다음과 같이 나타난다.



이상으로 멀티헤더를 구성하는 포스트를 마치겠습니다. 소스를 잘 보면 금방 분석이 될꺼라 생각이 들고, 완벽하게 멀티헤러를 보여주진 않지만 사용하는데 크게 문제가 되지 않는다고 생각이 든다.



'Development > C#' 카테고리의 다른 글

DataGridView의 포멧과 정렬사용하기  (0) 2017.08.22
DataGridView헤더에 CheckBox를 달자  (1) 2012.06.19