행이 수십 개 넘어가는 DataGridView는 가로로 시선을 따라가다 보면 윗줄과 아랫줄이 헷갈리기 쉽습니다. 엑셀 표처럼 한 줄씩 번갈아 연한 색을 깔아 주면 훨씬 읽기 편해지죠. 데이터를 다 채운 뒤에 행을 돌면서 배경색을 지정하는 가장 직접적인 방법입니다.

            for (int i = 1; i < this.Rows.Count; i++)
            {
                if (i % 2 != 0)
                {
                    this.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(240, 255, 240);
                }
                else
                {
                    this.Rows[i].DefaultCellStyle.BackColor = Color.White;
                }
            }

this로 시작하는 걸 보면 DataGridView를 상속한 사용자 정의 컨트롤 안에 넣어 둔 코드입니다. 폼에서 직접 쓸 때는 this 대신 dataGridView1처럼 컨트롤 이름으로 바꾸면 됩니다.

광고

코드가 하는 일

인덱스를 2로 나눈 나머지가 0이 아니면(홀수 번째 인덱스) 아주 연한 연두색 Color.FromArgb(240, 255, 240)을, 짝수면 흰색을 줍니다. 행마다 DefaultCellStyle을 바꾸는 방식이라 그 행의 모든 셀에 같은 색이 적용됩니다.

눈여겨볼 점은 반복이 i = 1부터 시작한다는 겁니다. 0번 행은 손대지 않으니 기본 배경색(보통 흰색)이 그대로 남고, 결과적으로 흰색-연두-흰색-연두 순서는 똑같이 나옵니다. 다만 0번 행에 다른 색이 들어가 있던 상태에서 다시 칠하는 경우라면 첫 줄만 그 색이 남으니, 확실하게 하려면 0부터 돌리는 편이 낫습니다.

정렬하거나 행을 추가하면 줄무늬가 깨진다

이 방식은 지금 화면에 있는 행에 색을 "칠해 두는" 것이라, 사용자가 열 머리글을 눌러 정렬하면 색이 행을 따라 같이 움직여서 줄무늬가 엉망이 됩니다. 행을 중간에 추가하거나 지워도 마찬가지고요. 그래서 이 코드를 쓴다면 데이터 바인딩이 끝난 뒤, 그리고 Sorted 이벤트 같은 곳에서 다시 한 번 호출해 주어야 합니다.

번거롭다면 DataGridView가 원래 가지고 있는 AlternatingRowsDefaultCellStyle 속성을 쓰는 게 간단합니다. 이 속성에 색을 지정해 두면 정렬이나 행 추가와 상관없이 화면에 보이는 순서대로 번갈아 칠해 줍니다.

dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(240, 255, 240);

반복문 방식은 "특정 조건에 맞는 행만 색을 다르게" 같은 응용을 할 때 쓸모가 있습니다. 예를 들어 i % 2 대신 셀 값을 검사해서 재고가 0인 행은 빨간색, 마감된 행은 회색으로 칠하는 식으로 바꿔 쓰면 됩니다. 이 경우에도 정렬 후 다시 칠해야 한다는 점은 같습니다.

색이 우선하는 순서

반복문으로 칠한 색과 AlternatingRowsDefaultCellStyle 을 같이 쓰면 반복문 쪽이 이깁니다. DataGridView는 셀 자체의 Style, 행의 DefaultCellStyle, AlternatingRowsDefaultCellStyle, RowsDefaultCellStyle, 열의 DefaultCellStyle, 그리드 전체의 DefaultCellStyle 순서로 값을 찾기 때문입니다. 속성으로 바꿨는데 줄무늬가 안 바뀐다면 예전 반복문이 어딘가에서 아직 행 스타일을 덮어쓰고 있지 않은지 먼저 확인해 보세요.

선택된 행은 SelectionBackColor 로 칠해지므로 줄무늬 색이 가려지는 게 정상입니다. 또 AllowUserToAddRows 가 켜져 있으면 맨 아래 빈 입력 행도 Rows.Count 에 들어가서, 반복문을 쓰면 그 행까지 색이 칠해집니다.

조건부 색은 CellFormatting에서

정렬해도 깨지지 않는 조건부 색칠이 필요하면 CellFormatting 이벤트에서 그때그때 색을 정하는 방법이 있습니다. 화면에 그릴 때마다 불리기 때문에 정렬이나 값 변경 뒤에 다시 칠하는 코드를 따로 둘 필요가 없습니다.

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.RowIndex < 0) return;
    DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
    if (row.IsNewRow) return;

    object v = row.Cells["Stock"].Value;
    if (v != null && v != DBNull.Value && Convert.ToInt32(v) == 0)
        e.CellStyle.BackColor = Color.MistyRose;
}

여기서 "Stock" 은 예시로 든 열 이름입니다. 이 이벤트는 셀마다 아주 자주 불리니 안에서 DB 조회 같은 무거운 일은 하지 말고, 값 비교 정도로만 가볍게 유지해야 스크롤이 버벅이지 않습니다.