DataGridView > ⓘ 개발

본문 바로가기
사이트 내 전체검색


회원로그인

ⓘ 개발

DataGridView

페이지 정보

작성자 SDJ 작성일17-05-21 00:19 조회1,963회 댓글0건

본문

글쓴이 : Jin (219.241.31.136)     날짜 : 07-09-03 16:00     조회 : 5738    

 

 

 

 

새로운 DataGridView

새 데이터 표 소개

Matthew MacDonald
새로운 DataGridView는 .NET 1.x의 표준이었으며 안타깝게도 제 역할을 하지 못한 DataGrid 컨트롤에 대해 .NET 2.0이 제시하는 해결책입니다. Matthew MacDonald가 아래에서 설명할 많은 개선 사항 중에서도 DataGridView는 광범위한 사용자 지정 및 세부적인 서식 지정, 유연한 크기 조정 및 선택, 뛰어난 성능 그리고 다양한 이벤트 모델을 지원합니다.
 
.NET Framework의 처음 두 릴리스(.NET 1.0 및 .NET 1.1)는 데이터 바인딩 부문에서 명백한 차이를 남겼습니다. 개발자들은 거의 모든 컨트롤을 거의 모든 데이터 원본에 연결할 수 있는 유연하고 구성 가능한 모델을 가지고 있었지만 전체 정보 테이블을 표시하기 위한 실질적인 방법은 없었습니다. 이를 위해 포함된 유일한 도구는 DataGrid 컨트롤로, 간단한 데모에서는 원활하게 작동했지만 실제 코드에서는 턱없이 부족한 성능을 나타냈습니다.
Microsoft는 이러한 격차를 줄이는 것을 .NET 2.0의 핵심 목표로 삼아 완전히 새로운 표 컨트롤인 DataGridView로 문제를 해결했습니다. DataGridView의 주요 원칙은 두 가지입니다. 먼저, 이 컨트롤은 단 몇 줄의 코드만 작성하여 마스터-세부 목록, 유효성 검사 및 데이터 서식 지정 같은 일반적인 작업을 지원하는 것을 목표로 합니다. 또한 무엇보다도 낮은 수준의 해킹 및 "편법" 프로그래밍에 의지하지 않고 필요한 특수 기능을 통합할 수 있도록 처음부터 확장성을 염두에 두고 디자인되었습니다.

기본적인 데이터 바인딩

DataGridView에 익숙해지는 가장 효과적인 방법은 속성을 하나도 구성하지 않고 직접 사용해 보는 것입니다. DataGrid와 마찬가지로 DataSource 속성을 사용하여 DataTable 개체(또는 DataTable에서 파생된 개체)를 바인딩할 수 있습니다.
Dim ds As DataSet = GetDataSet()
DataGridView1.DataSource = ds.Tables("Customers")
DataGrid와 달리 DataGridView는 테이블을 한 번에 하나씩만 나타낼 수 있습니다. 전체 DataSet를 바인딩하는 경우 나타낼 테이블 이름으로 DataMember 속성을 설정하지 않으면 아무런 데이터도 표시되지 않습니다.
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers"
기본적인 DataGridView 표시는 다음과 같은 몇 가지 간단한 규칙을 따릅니다.
  • 데이터 원본의 각 필드에 대해 한 열씩 만듭니다.
  • 필드 이름을 사용하여 열 헤더를 만듭니다. 열 헤더는 고정되어 있어 사용자가 목록 아래로 이동해도 계속 볼 수 있습니다.
  • Windows XP 방식의 표시 스타일을 지원합니다. 열 헤더는 세련된 평면 모양이며 사용자가 헤더 위로 마우스를 이동하면 강조 표시됩니다.
쉽게 눈에 띄지는 않지만 DataGridView에는 다음과 같은 다양한 기본 동작이 포함되어 있습니다.
  • 현재 위치 내 편집이 가능합니다. 사용자는 셀을 두 번 클릭하거나 F2 키를 눌러 현재 값을 수정할 수 있습니다. 유일한 예외는 필드의 DataColumn.ReadOnly가 true로 설정되어 있는 경우입니다(예: 현재 예제의 OrderID 필드).
  • 자동 정렬을 지원합니다. 사용자는 열 헤더를 한 번 또는 두 번 클릭하여 해당 필드의 값을 기반으로 값 순서를 오름차순 또는 내림차순으로 정할 수 있습니다. 기본적으로 정렬은 데이터 형식을 고려하며 사전순 또는 숫자 순서대로 이루어집니다. 사전순 정렬은 대/소문자를 구분합니다.
  • 다양한 형식을 선택할 수 있습니다. 사용자는 클릭하여 끌어 오는 방식으로 하나 이상의 셀 또는 여러 행을 강조 표시할 수 있습니다. DataGridView 왼쪽 위에 있는 사각형을 클릭하면 전체 테이블이 선택됩니다.
  • 자동 크기 조정 기능을 지원합니다. 사용자가 헤더 사이의 열 구분선을 두 번 클릭하면 왼쪽 열이 셀 내용에 맞게 자동으로 확장 또는 축소됩니다.

멋진 모양의 DataGridView 만들기

DataGridView의 기본 모양은 DataGrid에 비해 약간 개선되었습니다. 하지만 몇 가지 간단한 세부 작업을 통해 모양을 멋지게 다듬을 수 있습니다.
한 가지 문제는 열이 해당 데이터에 맞게 자동으로 확장되지 않는다는 것입니다. 이 문제는 DataGridView.AutoSizeColumns() 메서드와 DataGridViewAutoSizeColumnCriteria 열거형 값 중 하나를 사용하여 해결할 수 있습니다. 열의 크기는 헤더 텍스트 너비, 현재 표시된 행 또는 테이블의 모든 행을 기반으로 조정하도록 선택할 수 있습니다.
' 헤더에서 가장 큰 텍스트의 너비
' 또는 이 열의 행 중 하나에 대해
' 열 크기를 조정합니다.
DataGridView1.AutoSizeColumns( _
  DataGridViewAutoSizeColumnCriteria.HeaderAndRows)
 
(참고: 프로그래머 코멘트는 샘플 프로그램 파일에는 영문으로 제공되며 기사에는 설명을 위해 번역문으로 제공됩니다.)
이 메서드는 데이터 바인딩이 끝난 후 호출해야 하며 그렇지 않으면 어떤 영향도 미치지 않습니다. 또한 사용자가 편집한 후에 사용하는 경우도 있습니다(DataGridView.CellValueChanged 같은 이벤트에 대한 응답으로).
이에 맞게 열 크기를 넓히는 대신 행 크기를 변경할 수도 있습니다. 기본적으로 열의 텍스트는 여러 줄에 겹치게 됩니다. DataGridView.AutoSizeRows() 메서드를 사용하는 경우 행은 내용에 맞게 높이가 조정됩니다. 특히 필드에 텍스트의 양이 많은 경우에는 이 메서드를 사용하기 전에 열 크기를 넓혀야 할 수 있습니다. 예를 들어 다음 코드 조각은 Descript-xion 열의 크기를 네 배로 늘린 다음 내용에 맞게 행의 크기를 조정합니다.
DataGridView.Columns("Descript-xion").Width *= 4
DataGridView.AutoSizeRows( _
  DataGridViewAutoSizeRowsMode.HeaderAndColumnsAllRows)
그림 1에서는 DataGridView의 크기를 자동으로 조정하는 서로 다른 접근 방식을 비교합니다.
또 다른 적절한 변화 중 하나로 각 열에 나타나는 헤더 텍스트를 변경하는 기능을 들 수 있습니다. 예를 들어 필드 이름인 "OrderDate"보다는 "Order Date"라는 제목을 붙이는 것이 보다 전문적인 느낌을 줍니다. 이러한 변화는 매우 간단하게 이루어집니다. 다음과 같이 DataGridView.Columns 컬렉션에서 적절한 DataGridViewColumn을 검색한 다음 해당 HeaderText 속성을 수정하면 됩니다.
DataGridView.Columns("OrderID").HeaderText = "Order ID"

DataGridView를 사용하여 셀 선택

DataGridView를 사용하면 기본적으로 자유로운 선택이 가능합니다. 사용자는 개별 셀, 셀 그룹, 모든 셀을 한 번에(표 오른쪽 위의 사각형을 클릭하여) 또는 하나 이상의 행(헤더 열의 행을 클릭하여)을 강조 표시할 수 있습니다. 선택 모드에 따라 사용자는 열 헤더를 선택하여 하나 이상의 열을 선택할 수도 있습니다. 이 동작을 제어하려면 다음 설명과 같이 DataGridViewSelectionMode 열거형 값 중 하나로 DataGridView.SelectionMode 속성을 선택합니다.
  • CellSelect 셀은 선택할 수 있지만 전체 행 또는 헤더는 선택할 수 없습니다. DataGridView.MultiSelect가 True이면 여러 개의 셀을 선택할 수 있습니다.
  • FullColumnSelect 열 헤더를 클릭하여 전체 열만 선택할 수 있습니다. DataGridView.MultiSelect가 True이면 여러 개의 열을 선택할 수 있습니다. 이 모드를 사용하면 열 헤더를 클릭해도 표가 정렬되지 않습니다.
  • FullRowSelect 행 헤더를 클릭하여 전체 행만 선택할 수 있습니다. DataGridView.MultiSelect가 True이면 여러 개의 행을 선택할 수 있습니다.
  • ColumnHeaderSelect CellSelect 또는 FullColumnSelect 선택 모드를 사용할 수 있습니다. 이 모드를 사용하면 열 헤더를 클릭해도 표가 정렬되지 않습니다.
  • RowHeaderSelect CellSelect 또는 FullRowSelect 선택 모드를 사용할 수 있습니다. 이것이 기본 선택 모드입니다.
DataGridView는 다음 세 가지 속성을 사용하여 선택한 셀을 손쉽게 검색할 수 있도록 해줍니다. SelectedCells, SelectedRows 및 SelectedColumns. SelectedCells는 사용하는 선택 모드에 관계 없이 DataGridViewCell 개체의 컬렉션을 반환합니다. 반면 SelectedRows는 행 헤더를 선택하여 전체 행을 선택한 경우 정보만 반환하며 SelectedColumns는 열 헤더를 사용하여 전체 열을 선택한 경우 정보만 반환합니다.
예를 들어 다음 코드 조각은 선택한 전체 행을 확인합니다. 행을 찾으면 다음과 같이 메시지 상자에 CustomerID 열의 해당 값을 표시합니다.
For Each SelectedRow As DataGridViewRow In _
  DataGridView1.SelectedRows
    MessageBox.Show( _
      SelectedRow.Cells("CustomerID").Value)
Next
이 작업은 CurrentCell 또는 CurrentCellAddress 속성을 사용하여 현재 셀에 대한 참조를 검색하는 것만큼이나 간단합니다. DataGridView를 사용하면 현재 셀이 검정 점선 사각형 모양의 포커스 영역으로 둘러싸입니다. 이 영역이 현재 사용자의 위치입니다.
CurrentCellAddress 속성은 읽기 전용이지만 CurrentCell을 사용하면 현재 위치를 프로그래밍 방식으로 변경할 수 있습니다. 그런 후에 현재 위치가 표시되도록 DataGridView가 스크롤됩니다.
' 11번째 행의 네 번째 셀로 이동합니다.
DataGridView.CurrentCell = _
  DataGridView.Rows(10).Cells(3)
DataGridView 개체
지금까지는 현재 선택한 행, 셀 및 열 집합과 상호 작용하는 방법을 확인했습니다. DataGridView는 전체 데이터 집합을 작업할 수 있게 해주는 두 개의 주요 컬렉션을 제공합니다. 이들은 Columns(DataGridViewColumn 개체의 컬렉션) 및 Rows(각각 DataGridViewCell 개체의 컬렉션을 참조하는 DataGridViewRow 개체의 컬렉션)로 나타납니다. 그림 2는 개체 모델을 보여 줍니다.
일반적으로 열 표시 속성, 서식 지정 및 헤더 텍스트를 구성하려면 DataGridViewColumn 개체를 사용합니다. 또한 DataGridViewRow 및 DataGridViewCell 개체는 바인딩된 레코드에서 실제 데이터를 검색하는 데 사용합니다. DataGridViewCell의 데이터를 수정하면 다음과 같이 사용자가 편집하는 것과 동일한 방식으로 처리됩니다. 적절한 DataGridView 변경 이벤트가 발생되면 기본 DataTable이 수정됩니다.
이제 DataGridView 개체 모델을 이해했으므로 테이블을 순환하는 코드를 쉽게 만들 수 있습니다. 행, 열 또는 셀을 선택하기 위해 해야 할 일은 해당하는 DataGridViewRow, DataGridViewColumn 또는 DataGridViewCell 개체를 찾아 IsSelected 속성을 true로 설정하는 것뿐입니다.
다음 예제는 OrderID 필드가 100 미만인 모든 행을 프로그래밍 방식으로 선택합니다.
For Each Row As DataGridViewRow In DataGridView1.Rows
    If Row.Cells("OrderID").Value < 100 Then
        Row.Selected = True
    End If
Next
DataGridViewColumn에서 여러 개의 서로 다른 클래스가 파생되는 것에는 신경쓰지 않아도 됩니다. 이러한 클래스는 셀에서 값을 그리고 편집하는 방식을 제어할 수 있습니다. .NET에는 다음과 같은 5개의 미리 빌드된 DataGridView 열 클래스가 포함되어 있습니다. DataGridViewButtonColumn, DataGridViewCheckBoxColumn, DataGridViewComboBoxColumn, DataGridViewImageColumn 및 DataGridViewTextBoxColumn.

DataGridView 스타일

DataGridView를 디자인하는 데 발생하는 한 가지 문제는 서로 다른 수준의 서식 지정을 적용할 만큼 유연하면서 매우 큰 테이블에 대해서도 효과적인 서식 지정 시스템을 만드는 것이었습니다. 유연성을 고려할 경우 최상의 접근 방식은 개발자가 각 셀을 개별적으로 구성할 수 있게 하는 것입니다. 그러나 효율성 측면에서 보면 이 접근 방식은 매우 열악하다고 할 수 있습니다. 테이블에 행이 수천 개면 셀은 수만 개가 되므로 셀마다 개별적으로 서식 지정을 관리한다는 것은 보나마나 많은 양의 메모리만 낭비하는 헛수고가 될 것입니다.
이 문제를 해결하기 위해 DataGridView는 DataGridViewCellStyle 개체를 사용하는 다계층 모델을 사용합니다. DataGridViewCellStyle 개체는 셀의 스타일을 나타내며 색, 글꼴, 맞춤, 줄 바꿈 및 데이터 서식 지정 같은 세부 사항이 포함되어 있습니다. 단일 DataGridViewCellStyle을 만들면 전체 테이블의 기본 서식을 지정할 수 있습니다. 또한 열, 행 및 개별 셀에 대해 기본 서식을 지정할 수 있습니다. 서식을 보다 세부적으로 지정할수록 더 많은 DataGridViewCellStyle 개체를 만들며 솔루션의 확장 가능성은 떨어지게 됩니다. 그러나 주로 열 기반 및 행 기반 서식 지정을 사용하고 개별 셀의 서식은 가끔씩 지정하는 경우 DataGridView의 메모리가 DataGrid보다 훨씬 많을 필요는 없습니다.
DataGridView는 서식 지정을 적용할 때 다음과 같은 우선 순위를 따릅니다(내림차순으로).
1. DataGridViewCell.Style
2. DataGridViewRow.DefaultCellStyle
3. DataGridView.AlternatingRowsDefaultCellStyle
4. DataGridView.RowsDefaultCellStyle
5. DataGridViewColumn.DefaultCellStyle
6. DataGridView.DefaultCellStyle
여기서 이해해야 할 부분은 스타일 개체가 전혀 적용되지 않는다는 점입니다. 대신 DataGridView는 각 개별 속성을 확인합니다. 예를 들어 DataGridViewCell.Style 속성을 사용하여 사용자 지정 글꼴을 적용하지만 사용자 지정 전경색은 설정하지 않는 셀이 있다고 가정합시다. 이렇게 되면 글꼴 설정은 다른 모든 스타일 개체의 글꼴 정보보다 우선하여 적용되지만 전경색은 null이 아닌 경우 계층 구조의 다음 스타일 개체에서 상속됩니다(이 경우 DataGridViewRow.DefaultCellStyle).
DataGridViewCellStyle은 다음과 같은 두 가지 유형의 서식 지정을 정의합니다. 데이터 및 모양. 데이터 서식 지정이란 데이터 바인딩된 값이 표시되기 전에 수정되는 방식을 지정하는 것을 말합니다. 여기에는 일반적으로 서식 지정 문자열을 사용하여 숫자 또는 날짜 값을 텍스트로 전환하는 작업이 포함됩니다. 데이터 서식 지정을 사용하려면 DataGridViewCellStyle.Format 속성을 사용하여 형식 지정자 또는 사용자 지정 형식 문자열을 설정하면 됩니다.
예를 들어 다음 코드 조각은 UnitCost 필드에 있는 모든 숫자의 서식을 지정하여 이들 숫자가 통화 값으로 표시되고 두 개의 소수 자릿수와 적절한 통화 기호가 로캘 설정에 정의됩니다.
DataGridView1.Columns("UnitCost"). _
  DefaultCellStyle.Format = "C"
모양 서식 지정에는 색 및 글꼴 같은 표면적인 묘사가 포함되어 있습니다. 예를 들어 다음 코드는 UnitCost 필드를 오른쪽으로 맞추고 굵은 글꼴을 적용하며 셀 배경을 노랑으로 변경합니다.
DataGridView1.Columns("UnitCost"). _
  DefaultCellStyle.Font = _
  New Font(DataGridView.Font, FontStyle.Bold)
DataGridView1.Columns("UnitCost"). _
  DefaultCellStyle.Alignment = _
  DataGridViewContentAlignment.MiddleRight
DataGridView1.Columns("UnitCost"). _
  DefaultCellStyle.BackColor = Color.LightYellow
다른 서식 지정 관련 속성에는 ForeColor, SelectionForeColor, SelectionBackColor, WrapMode(공간이 허용되는 경우 텍스트를 여러 줄에 겹치게 할지 잘라낼지 여부를 제어) 및 NullValue(null 값을 대체하는 값)가 있습니다.
또한 DataGridView에는 디자인 타임에 열 스타일을 구성할 수 있게 해주는 디자이너가 포함되어 있습니다. 속성 창에서 DataGridView Properties 링크를 선택하거나 AutoFormat을 선택하여 다양한 미리 빌드된 스타일 설정에서 선택하면 됩니다.

사용자 지정 셀 서식 지정

셀의 서식을 지정하기 위해 첫 번째로 선택할 사항은 상위 DataGridView, DataGridViewColumn 및 DataGridViewRow 속성을 통해 작업하는 것입니다. 그러나 때로는 특정 개별 셀의 스타일을 설정해야 하는 경우도 있습니다. 예를 들어 열의 데이터가 특정 값보다 크거나 작으면 데이터를 플래그해야 하는 경우가 있습니다. 이에 대한 한 가지 예는 프로젝트 일정 목록에서 기한이 경과된 만기일 또는 매출 분석에서 마이너스 수익률을 강조 표시하는 것입니다. 위의 두 경우 모두 개별 셀의 서식을 지정해야 합니다.
DataGridView 개체 모델에 대한 지식을 활용하여 값을 강조 표시할 것으로 예상되는 특정 열에서 셀의 컬렉션을 반복하고 싶을 수도 있습니다. 이러한 접근 방식은 사용할 수는 있지만 최선의 선택은 아닙니다. 여기서 중요한 문제는 사용자가 데이터를 편집하거나 코드가 바인딩된 데이터 원본을 변경하는 경우 셀 강조 표시가 일치하도록 업데이트되지 않는다는 것입니다.
다행히도 DataGridView는 이를 위해 CellFormatting 이벤트를 제공합니다. CellFormatting은 셀 값이 그려지기 직전에 발생되며 내용을 기반으로 셀 스타일을 업데이트할 수 있습니다. 다음은 특정 고객을 확인하여 그에 따라 셀을 플래그하는 예제입니다.
Private Sub DataGridView1_CellFormatting( _
  ByVal sender As System.Object, _
  ByVal e As System.Windows.Forms. _
  DataGridViewCellFormattingEventArgs) _
  Handles DataGridView1.CellFormatting

    ' 맞는 열인지 확인합니다.
    If DataGridView1.Columns(e.ColumnIndex).Name = _
      "CustomerID" Then
        ' 맞는 값인지 확인합니다.
        If e.Value = "ALFKI" Then
            e.CellStyle.ForeColor = Color.Red
            e.CellStyle.BackColor = Color.Yellow
        End If
    End If
End Sub
표의 모양에 영향을 주는 세부 사항은 스타일뿐만이 아닙니다. 사용자가 오른쪽으로 스크롤하더라도 계속 표시되도록 열을 숨기고 위치를 이동하며 잠글 수도 있습니다. 이러한 기능은 모두 다음 설명과 같이 DataGridViewColumn 클래스의 속성을 통해 제공됩니다.
  • DisplayIndex DataGridView에서 열이 표시되는 위치를 설정합니다. 예를 들어 DisplayIndex가 0인 열은 가장 왼쪽 열에 자동으로 표시됩니다. DisplayIndex가 동일한 열이 둘 이상이면 컬렉션의 첫 번째 열이 가장 먼저 표시됩니다. 따라서 DisplayIndex를 사용하여 열을 왼쪽으로 옮기는 경우 가장 왼쪽 열의 DisplayIndex도 오른쪽으로 옮기도록 설정해야 합니다. 처음에 DisplayIndex는 DataGridView.Columns 컬렉션의 DataGridViewColumn 개체의 인덱스와 일치합니다.
  • Frozen True인 경우 사용자가 추가 열을 확인하기 위해 오른쪽으로 스크롤해도 테이블 왼쪽에 표시된 상태로 고정됩니다.
  • HeaderText 열 헤더에 표시되는 텍스트를 설정합니다.
  • Resizable 및 MinimumWidth Resizable을 False로 설정하여 사용자가 열 크기를 조정하지 못하게 하거나 MinimumWidth를 최소 허용 픽셀 수로 설정합니다.
  • Visible False로 설정하여 열을 숨깁니다.

단추 열

DataGridView를 위해 제공되는 열 형식 중 하나는 모든 항목 옆에 단추를 표시하는 DataGridViewButtonColumn입니다. 이 단추의 클릭에 응답하는 것은 물론 이를 사용하여 다른 작업을 시작하거나 새 폼을 표시할 수도 있습니다.
다음은 단추 텍스트가 "Details..."인 간단한 단추 열을 만드는 예제입니다.
' 단추 열을 만듭니다.
Dim Details As New DataGridViewButtonColumn()
Details.Name = "Details"

' 데이터 바인딩을 해제하고 정적 텍스트를 표시합니다.
' (대신 DataPropertyName 속성을 설정하여
' 테이블의 속성을 사용할 수도 있습니다.)
Details.DisplayTextAsFormattedValue = False
Details.Text = "Details..."

' 헤더를 지웁니다.
Details.HeaderText = ""

' 열을 추가합니다.
DataGridView1.Columns.Insert( _
  DataGridView1.Columns.Count, Details)
그림 3은 새 열이 표시된 표를 보여 줍니다. 다음은 모든 열에서 단추 클릭에 반응하여 해당되는 레코드 정보를 표시하는 코드입니다.
Private Sub DataGridView1_CellClick( _
  ByVal sender As System.Object, _
  ByVal e As System.Windows.Forms. _
  DataGridViewCellEventArgs) _
  Handles DataGridView1.CellClick

    If DataGridView1.Columns(e.ColumnIndex).Name = _
      "Details" Then
        MessageBox.Show("You picked " & _
          DataGridView1.Rows(e.RowIndex). _
          Cells("CustomerID").Value)
    End If
End Sub
좀 더 현실적인 시나리오에서는 여기서 새 창을 만들고 표시한 다음 선택한 레코드에 대한 정보를 새 창으로 전달하여 전체 정보를 쿼리하고 표시할 수 있도록 합니다.

이미지 열

DataGridView를 위해 제공되는 또 다른 열 형식은 셀 범위에 그림을 표시하는 DataGridViewImageColumn입니다. DataGridViewImageColumn.Layout 속성을 설정하면 크기에 맞게 늘이든 너무 큰 경우 그냥 잘라내든 간에 셀에 그림이 표시되는 방법을 구성할 수 있습니다.
DataGridViewImageColumn은 다음 두 가지 방법으로 사용할 수 있습니다. 먼저, DataGridViewButtonColumn과 동일한 방식으로 직접 이를 만들어 추가할 수 있습니다. 이 방법은 DataSet에 제공되지 않는 관련된 이미지 데이터를 표시하려는 경우에 유용합니다. 예를 들어 파일 이름(예: ProductPic002.gif)을 가져와 네트워크 드라이브에서 해당 파일을 읽은 다음 이를 표에 표시하는 경우가 있습니다. 이를 수행하려면 CellFormatting처럼 DataGridView 이벤트에 반응해야 하며, 이 때 열의 Value 속성을 사용하여 해당하는 행의 그림을 읽고 이미지 데이터를 가져오며 이를 삽입합니다.
DataSet에 수작업이 필요 없는 이진 그림 데이터가 들어 있으면 상황은 훨씬 간단해집니다. 이에 대한 한 가지 예는 회사 로고가 포함되어 있는 SQL Server pubs 데이터베이스의 pub_info 테이블입니다. 이 테이블에 바인딩할 때는 추가 단계를 수행할 필요 없이 DataGridView가 현재 이미지를 사용하고 있음을 자동으로 인식하여 필요한 DataGridViewImageColumn을 만들어 줍니다. (이 기법의 예제는 이 기사의 다운로드를 참조하십시오.)

DataGridView를 사용하는 편집

DataGrid는 사용자 입력에 유연성이 떨어지기로 악명 높아 셀의 유효성을 검사하고 오류를 보고하는 방식을 사용자 지정하기가 거의 불가능했습니다. 반면 DataGridView를 사용하면 편집 프로세스의 모든 단계에서 발생하는 수많은 서로 다른 단계에 반응하여 동작을 제어할 수 있습니다.
기본적으로 DataGridView 셀은 사용자가 마우스로 셀을 두 번 클릭하거나 F2 키를 누르면 편집 모드로 들어갑니다. 또한 DataGridView.EditCellOnEnter 속성을 true로 설정하면 사용자가 셀로 이동하자마자 편집 모드로 전환되도록 DataGridView를 구성할 수 있습니다. DataGridView의 BeginEdit(), CancelEdit(), CommitEdit() 및 EndEdit() 메서드를 사용하여 셀 편집을 프로그래밍 방식으로 시작 및 중단할 수도 있습니다. 사용자가 셀을 편집하면 행 헤더에 연필 모양의 편집 아이콘이 표시됩니다.
사용자가 Esc 키를 누르면 편집을 취소할 수 있습니다. EditCellOnEnter 속성을 true로 설정하면 셀이 편집 모드로 유지되지만 모든 변경 내용이 삭제됩니다. 변경을 커밋하려면 사용자가 새로운 셀로 이동하거나 포커스를 다른 컨트롤로 변경하면 됩니다. 코드에서 현재 셀 위치를 옮기면 변경 내용도 함께 커밋됩니다.
셀을 편집하지 못하게 하려면 DataGridViewCell, DataGridViewColumn, DataGridViewRow 또는 DataGridView의 ReadOnly 속성을 설정하면 됩니다(변경하지 못하게 하려는 대상이 해당 셀인지, 해당 열의 모든 셀인지, 해당 행의 모든 셀인지 또는 테이블의 모든 셀인지에 따라 다름). DataGridView는 또한 시도한 편집을 취소하기 위해 처리할 수 있는 CellBeginEdit 이벤트를 노출합니다.

오류 처리

기본적으로 DataGridViewTextBoxColumn을 사용하면 사용자가 현재 셀에 허용되지 않을 수 있는 문자를 포함하여 모든 문자를 입력할 수 있습니다. 예를 들어 사용자가 숫자 필드에 숫자가 아닌 문자를 입력하거나 DataSet에 정의된 ForeignKeyConstraint 또는 UniqueConstraint를 위반하는 값을 지정할 수도 있습니다. DataGridView는 이러한 문제를 다음과 같이 다양한 방식으로 처리합니다.
  • 편집한 값을 필요한 데이터 형식으로 변환할 수 있으면(예: 사용자가 숫자 열에 텍스트를 입력한 경우) 사용자는 변경 내용을 커밋하거나 다른 행으로 이동할 수 없게 됩니다. 대신 변경 내용을 취소하거나 값을 편집해야 합니다.
  • 편집한 값이 DataSet의 제약 조건을 위반하는 경우 사용자가 다른 행으로 이동하거나 Enter 키를 눌러 이를 커밋하고 나면 바로 변경 내용이 취소됩니다.
이처럼 명백한 기본값은 대부분의 시나리오에서 원활하게 적용됩니다. 그러나 필요한 경우 DataGridView가 데이터 원본에서 오류를 차단할 때 발생하는 DataGridView.DataError 이벤트에 응답하여 오류 처리에 참가할 수도 있습니다.

입력 유효성 검사

유효성 검사는 오류 처리와는 약간 다른 작업입니다. 오류 처리의 경우 DataSet를 통해 보고되는 문제를 처리합니다. 하지만 유효성 검사의 경우 DataSet에는 허용될 수 있지만 응용 프로그램에는 적절하지 않은 데이터 같은 고유한 사용자 지정 오류 조건을 찾아냅니다.
사용자가 새로운 셀로 이동하여 변경 내용을 커밋하면 DataGridView 컨트롤은 CellValidating 및 CellValidated 이벤트를 발생시킵니다. 또한 이러한 이벤트 다음에는 RowValidating 및 RowValidated 이벤트가 발생됩니다. 여러분은 이러한 이벤트에 응답하고 사용자가 입력한 값이 올바른지 확인하며 필요한 처리 후 작업을 수행할 수 있습니다. 값이 올바르지 않으면 일반적으로 변경 내용 및 셀 탐색을 취소하거나(EventArgs 개체의 Cancel 속성을 true로 설정하여) 사용자에게 알려줄 몇 가지 오류 텍스트를 설정하여 응답하게 됩니다. 오류 텍스트는 다른 컨트롤에 배치하거나 다음과 같이 해당하는 DataGridViewRow 및 DataGridViewCell의 ErrorText 속성을 사용하여 DataGrid에 표시할 수 있습니다.
  • DataGridViewCell.ErrorText를 설정하면 셀에 느낌표 아이콘이 표시됩니다. 마우스로 이 아이콘을 가리키면 오류 메시지가 표시됩니다.
  • DataGridViewRow.ErrorText를 설정하면 행 왼쪽의 행 헤더에 느낌표 아이콘이 표시됩니다. 마우스로 이 아이콘을 가리키면 오류 메시지가 표시됩니다.
일반적으로 이들 속성은 모두 함께 사용하며 행과 셀 모두에 오류 메시지를 설정하게 됩니다. 다음은 CompanyName 필드의 너무 긴 텍스트 항목을 확인하는 예제입니다. 문제가 되는 값을 발견하면 문제가 설명된 도구 설명 텍스트와 함께 오류 그림(빨강 느낌표 표시)이 셀에 추가됩니다.
Private Sub DataGridView1_CellValidating( _
  ByVal sender As System.Object, _
  ByVal e As System.Windows.Forms. _
  DataGridViewCellValidatingEventArgs) _
  Handles DataGridView1.CellValidating

    If DataGridView1.Columns(e.ColumnIndex).Name = _
      "CompanyName" Then
        If CType(e.FormattedValue, String).Length > _
          50 Then
            DataGridView1.Rows( _
              e.RowIndex).Cells(e.ColumnIndex). _
              ErrorText = _
              "회사 이름이 너무 깁니다."
        End If
    End If
End Sub
목록 열로 선택 사항 제한
유효성 검사를 사용하면 모든 오류 조건을 잡아낼 수 있습니다. 그러나 이 접근 방식을 사용하면 잘못된 내용을 입력한 다음 이를 사후에 수정할 수 있기 때문에 반드시 최선의 방법이라고 할 수는 없습니다. 보다 바람직한 방법은 우선 사용자가 잘못된 내용을 입력하지 못하도록 하는 것입니다.
한 가지 일반적인 예는 열을 미리 정의한 값 목록으로 제한해야 하는 경우에 나타납니다. 이 시나리오에서는 사용자가 직접 입력하기보다 목록에서 올바른 값을 선택하는 것이 가장 쉽습니다. 무엇보다도 DataGridViewComboBoxColumn을 사용하면 이 디자인을 가장 손쉽게 구현할 수 있습니다.
DataGridViewComboBoxColumn의 항목 목록은 ListBox에서처럼 항목 컬렉션을 사용하여 직접 추가할 수 있습니다. 또한 DataGridViewComboBoxColumn을 또 다른 데이터 원본에 바인딩할 수 있습니다. 이 경우 DataSource 속성을 사용하여 데이터 원본을 지정하고 DisplayMember 속성을 사용하여 열에 표시해야 하는 값을 나타내며 ValueMember 속성을 사용하여 기본 열 값에 사용해야 하는 값을 나타냅니다.
이에 대한 데모로 Products 테이블에 작업하는 다음 예제를 살펴보겠습니다. 이 테이블의 모든 레코드는 해당 CategoryID 필드를 통해 Categories 테이블의 레코드에 연결되어 있습니다. 제품의 범주를 변경하려면 사용자는 올바른 ID를 기억하여 CategoryID 필드에 입력해야 합니다. 보다 나은 방법은 Categories 테이블에 바인딩되는 DataGridViewComboBoxColumn을 사용하는 것입니다. 이 열은 CategoryName을 표시 멤버로 사용하지만 실제 기본 값으로 CategoryID를 갖게 됩니다. 또한 이 열은 DataProperyName 속성을 통해 Products 테이블에 계속 바인딩되어 사용자가 목록에서 새 Category를 선택하면 제품 레코드의 CategoryID 필드가 자동으로 변경됩니다.
다음은 이 테이블을 구성하는 데 필요한 코드입니다.
' 자동으로 생성된 CategoryID 열을 제거합니다.
DataGridView1.Columns.Remove("CategoryID")

' CategoryID의 목록 열을 만듭니다.
Dim List As New DataGridViewComboBoxColumn()
List.DisplayIndex = 0
List.HeaderText = "Category"

' 이 열은
' Products.CategoryID 필드에 바인딩됩니다.
List.DataPropertyName = "CategoryID"

' Categories 테이블에서 목록을 채웁니다.
List.DataSource = ds.Tables("Categories")
List.DisplayMember = "CategoryName"
List.ValueMember = "CategoryID"

' 열을 추가합니다.
DataGridView1.Columns.Add(List)
결론
이 기사에서는 .NET에서 가장 기대되는 새로운 컨트롤 중 하나인 DataGridView의 개요를 설명했습니다. DataGrid와 달리 DataGridView는 데이터 바인딩 및 사용자 편집 시나리오와 정적 테스트의 표시와만 관련된 시나리오를 포함하여 다양한 실제 시나리오에서 올바르게 작동합니다. 머지 않아 .NET Framework가 설치된 통합 기능 데이터 솔루션이자 Windows Forms 개발자들이 .NET 2.0으로 업그레이드하려는 가장 큰 이유 중 하나인 DataGridView를 직접 경험할 수 있을 것입니다.

 

 

 

 

[이 게시물은 SDJ님에 의해 2017-05-21 00:35:51 ⓘ 웹에서 이동 됨]

댓글목록

등록된 댓글이 없습니다.

ⓘ 개발 목록

게시물 검색

접속자집계

오늘
331
어제
303
최대
1,010
전체
349,175
회사소개 개인정보취급방침 서비스이용약관 Copyright © sdj.kr All rights reserved.
상단으로
모바일 버전으로 보기