유경상 (ksyu@tysystems.com)
DataGridColumn 클래스
DataGridColumn 클래스는 데이터그리드의 컬럼 정보를 갖는 클래스로서 중요한 역할을 수행한다. 이 클래스는 추상(abstract) 클래스로서 인스턴스를 가질 수 없다. 따라서 실제 데이터그리드의 컬럼은 DataGridColumn에서 파생된 BoundColumn, ButtonColumn, EditCommandColumn, HyperLinkColumn, TemplateColumn 클래스 중 하나이다. 이들 클래스는 모두 웹 컨트롤이 아니다. 즉, System.Web.UI.Control 클래스에서 파생된 것이 아니라는 것이다. 하지만 이들 클래스들은 각 TableCell 컨트롤이 어떤 자식 컨트롤을 가질 것인가를 결정한다.
데이터그리드는 Columns 컬렉션에 컬럼들의 리스트를 보유하게 된다. Columns 컬렉션에 컬럼을 추가하는 것은 디자인 타임이나 런타임에 가능하다. 디자인 타임에 설정되는 컬럼들은 aspx 파일내의 ASP.NET 태그를 통해 수행될 수 있으며, 이 태그들은 Columns 컬렉션에 DataGridColumn에서 파생된 컬럼 객체를 추가하는 코드로 변환된다. AutoGenerateColumn 속성 값이 True라면 데이터바인딩이 수행될 때 데이터소스의 컬럼 정보를 통해 BoundColumn 클래스의 인스턴스가 생성된다. 주의할 점은 AutoGenerateColumn 속성에 의해 생성된 BoundColumn 클래스는 Columns 컬렉션을 통해 액세스할 수 없다는 점이다.
DataGridColumn 클래스의 중요한 메쏘드는 InitializeCell 메쏘드이다. 이 메쏘드는 protected virtual 메쏘드로서 데이터그리드가 DataGridItem의 인스턴스를 만든 후, 데이터그리드에 설정된 각 컬럼(AutoGenerateColumn에 의해 생성된 컬럼에 대해서도)에 대해 호출한다. InitializeCell 메쏘드는 매개변수로 초기화할 TableCell 객체, 컬럼의 인덱스, DataGridItem의 타입을 매개변수로 취하며 이들에 의해 적절히 TableCell 객체를 초기화한다. 이 메쏘드에서 TableCell의 자식 컨트롤을 생성하기도 하며, 보다 중요한 것은 데이터바인딩을 수행할 DataBind 이벤트의 이벤트 핸들러를 설정한다는 점이다.
<리스트 1>은 BoundColumn 클래스의 InitiailzeCell 메쏘드이다. 이 메쏘드를 살펴보면 현재 TableCell이 속한 DataGridItem의 ItemType에 의거하여 TableCell을 초기화하는 작업을 담고 있다. DataGridItem이 EditItem이라면 자식 컨트롤로서 TextBox를 생성한다는 점과 데이터 바인딩 이벤트를 이 클래스의 OnDataBindColum 메쏘드로 설정한다는 점을 유심히 살펴보자. 데이터 바인딩이 일어나면 TableCell의 데이터 바인딩 메쏘드인 DataBind가 호출될 것이며 TableCell의 DataBind 메쏘드는 DataBind 이벤트를 발생하고 자식 컨트롤의 DataBind를 호출될 것이다. 따라서 자식 컨트롤의 존재 여부와 관계없이 데이터 바인딩은 BoundColumn 클래스의 OnDataBindColumn 메쏘드 내부에서 이뤄진다는 말이다.
TableCell 컨트롤이나 그 자식 컨트롤은 데이터소스가 어떤 것인지 그리고 데이터소스 내에서 어떤 컬럼에 바인딩될 것인지 전혀 알지 못하므로 데이터 바인딩을 수행할 수 있는 객체는 BoundColumn 객체가 되는 것은 매우 자연스럽다고 할 수 있다. BoundColumn은 바인딩할 데이터 필드(DataField 속성)의 이름을 알고 있으며 DataGridItem 컨트롤의 DataItem 속성은 바인딩할 데이터의 행(row)을 나타내고 있으므로(DataBind 이벤트의 sender 매개변수를 통해 DataGriItem 컨트롤이 전달될 것이다) 데이터 바인딩을 수행할 수 있는 것이다.
DataGridColumn 클래스와 그 자식 클래스는 TableCell과 밀접한 관계를 가지고 있으며 데이터 바인딩에서도 중요한 역할을 수행함을 알 수 있을 것이다. 필요에 따라 DataGridColumn 클래스를 상속하여 커스텀 컬럼을 만들 수도 있다. 몇몇 필수적인 메쏘드와 프로퍼티를 구현하기만 하면 원하는 HTML을 렌더링하도록 구성이 가능할 것이다. 이에 대한 상세한 내용은 이 글의 범위에서 벗어나므로 생략하기로 한다.
그 외의 클래스들
지금까지 설명한 컨트롤과 클래스들 외에도 데이터그리드와 연관된 클래스들은 데이터그리드 클래스의 베이스 클래스인 BaseDataList 클래스, 데이터그리드의 각종 스타일에 대한 TableItemStyle 클래스, 페이징에 대한 추상화를 제공하는 PagedDataSource 클래스, DataGridItem과 DataGridColumn에 대한 컬렉션을 제공하는 DataGridItemCollection 클래스, DataGridColumnCollection 클래스 등의 클래스가 있다. 이들 클래스들은 데이터그리드가 작동하는데 직간접적으로 관여한다. 특히 BaseDataList 클래스는 데이터리스트 컨트롤과 데이터그리드 컨트롤에 대한 베이스 클래스로서 데이터바인딩을 지원하는 리스트 컨트롤의 공통적인 인터페이스와 구현을 제공한다.
데이터그리드 컨트롤에 대한 분석을 하고자 한다면 시작점은 BaseDataList가 돼야 할 것이다. PagedDataSource 클래스는 데이터그리드의 데이터소스 속성에 설정된 데이터 소스에 대한 페이징 뷰를 제공한다. 예를 들어 데이터소스가 30개의 레코드를 갖고 PageSize가 10인 상태에서 AllowPagaing이 True라면 PagedDataSource는 현재 페이지의 10개 레코드만을 반환하고 AllowPagaing이 False라면 현재 페이지에 관계 없이 전체 30개의 레코드를 반환한다. PagedDataSource 클래스의 이러한 데이터소스 추상화는 데이터그리드 컨트롤이 AllowPaging 속성에 관계없이 단일 코드 플로우(flow)를 갖도록 해준다. 그 외의 클래스는 데이터그리드의 외양을 제어하고 컬렉션을 구현하는 데 이용된다.
데이터그리드 제어 흐름
데이터그리드의 구조를 살펴봤으니 이제 제어의 흐름을 살펴보자. 데이터그리드도 역시 일반적인 웹 컨트롤의 일종이므로 웹 컨트롤의 일반 제어 흐름을 따른다. 웹 컨트롤의 일반적인 제어 흐름과 데이터그리드의 구체적인 작업은 <표 1>과 같다. 데이터그리드의 전체 제어 흐름을 설명하기에는 그 분량이 너무 많으므로 핵심적인 몇몇 사항과 주의해야 할 사항에 대해서만 언급하기로 한다.
DataGridColumn 클래스
DataGridColumn 클래스는 데이터그리드의 컬럼 정보를 갖는 클래스로서 중요한 역할을 수행한다. 이 클래스는 추상(abstract) 클래스로서 인스턴스를 가질 수 없다. 따라서 실제 데이터그리드의 컬럼은 DataGridColumn에서 파생된 BoundColumn, ButtonColumn, EditCommandColumn, HyperLinkColumn, TemplateColumn 클래스 중 하나이다. 이들 클래스는 모두 웹 컨트롤이 아니다. 즉, System.Web.UI.Control 클래스에서 파생된 것이 아니라는 것이다. 하지만 이들 클래스들은 각 TableCell 컨트롤이 어떤 자식 컨트롤을 가질 것인가를 결정한다.
데이터그리드는 Columns 컬렉션에 컬럼들의 리스트를 보유하게 된다. Columns 컬렉션에 컬럼을 추가하는 것은 디자인 타임이나 런타임에 가능하다. 디자인 타임에 설정되는 컬럼들은 aspx 파일내의 ASP.NET 태그를 통해 수행될 수 있으며, 이 태그들은 Columns 컬렉션에 DataGridColumn에서 파생된 컬럼 객체를 추가하는 코드로 변환된다. AutoGenerateColumn 속성 값이 True라면 데이터바인딩이 수행될 때 데이터소스의 컬럼 정보를 통해 BoundColumn 클래스의 인스턴스가 생성된다. 주의할 점은 AutoGenerateColumn 속성에 의해 생성된 BoundColumn 클래스는 Columns 컬렉션을 통해 액세스할 수 없다는 점이다.
DataGridColumn 클래스의 중요한 메쏘드는 InitializeCell 메쏘드이다. 이 메쏘드는 protected virtual 메쏘드로서 데이터그리드가 DataGridItem의 인스턴스를 만든 후, 데이터그리드에 설정된 각 컬럼(AutoGenerateColumn에 의해 생성된 컬럼에 대해서도)에 대해 호출한다. InitializeCell 메쏘드는 매개변수로 초기화할 TableCell 객체, 컬럼의 인덱스, DataGridItem의 타입을 매개변수로 취하며 이들에 의해 적절히 TableCell 객체를 초기화한다. 이 메쏘드에서 TableCell의 자식 컨트롤을 생성하기도 하며, 보다 중요한 것은 데이터바인딩을 수행할 DataBind 이벤트의 이벤트 핸들러를 설정한다는 점이다.
<리스트 1> BoundColumn.InitiaizeCell 메쏘드
public virtual void InitializeCell(TableCell cell, int columnIndex, ListItemType itemType)
{
Control childControl;
Control bindingControl;
TextBox textBox;
base.InitializeCell(cell, columnIndex, itemType);
childControl = null;
bindingControl = null;
switch (itemType) {
case ListItemType.Item:
case ListItemType.AlternatingItem:
case ListItemType.SelectedItem:
if (this.DataField.Length == 0)
break;
bindingControl = cell;
break;
case ListItemType.EditItem:
if (this.ReadOnly)
goto case ListItemType.SelectedItem;
textBox = new TextBox();
childControl = textBox;
if (this.boundField.Length != 0)
bindingControl = textBox;
break;
}
if (childControl != null)
cell.Controls.Add(childControl);
if (bindingControl != null)
bindingControl.DataBinding += new EventHandler(this, OnDataBindColumn);
}
public virtual void InitializeCell(TableCell cell, int columnIndex, ListItemType itemType)
{
Control childControl;
Control bindingControl;
TextBox textBox;
base.InitializeCell(cell, columnIndex, itemType);
childControl = null;
bindingControl = null;
switch (itemType) {
case ListItemType.Item:
case ListItemType.AlternatingItem:
case ListItemType.SelectedItem:
if (this.DataField.Length == 0)
break;
bindingControl = cell;
break;
case ListItemType.EditItem:
if (this.ReadOnly)
goto case ListItemType.SelectedItem;
textBox = new TextBox();
childControl = textBox;
if (this.boundField.Length != 0)
bindingControl = textBox;
break;
}
if (childControl != null)
cell.Controls.Add(childControl);
if (bindingControl != null)
bindingControl.DataBinding += new EventHandler(this, OnDataBindColumn);
}
<리스트 1>은 BoundColumn 클래스의 InitiailzeCell 메쏘드이다. 이 메쏘드를 살펴보면 현재 TableCell이 속한 DataGridItem의 ItemType에 의거하여 TableCell을 초기화하는 작업을 담고 있다. DataGridItem이 EditItem이라면 자식 컨트롤로서 TextBox를 생성한다는 점과 데이터 바인딩 이벤트를 이 클래스의 OnDataBindColum 메쏘드로 설정한다는 점을 유심히 살펴보자. 데이터 바인딩이 일어나면 TableCell의 데이터 바인딩 메쏘드인 DataBind가 호출될 것이며 TableCell의 DataBind 메쏘드는 DataBind 이벤트를 발생하고 자식 컨트롤의 DataBind를 호출될 것이다. 따라서 자식 컨트롤의 존재 여부와 관계없이 데이터 바인딩은 BoundColumn 클래스의 OnDataBindColumn 메쏘드 내부에서 이뤄진다는 말이다.
TableCell 컨트롤이나 그 자식 컨트롤은 데이터소스가 어떤 것인지 그리고 데이터소스 내에서 어떤 컬럼에 바인딩될 것인지 전혀 알지 못하므로 데이터 바인딩을 수행할 수 있는 객체는 BoundColumn 객체가 되는 것은 매우 자연스럽다고 할 수 있다. BoundColumn은 바인딩할 데이터 필드(DataField 속성)의 이름을 알고 있으며 DataGridItem 컨트롤의 DataItem 속성은 바인딩할 데이터의 행(row)을 나타내고 있으므로(DataBind 이벤트의 sender 매개변수를 통해 DataGriItem 컨트롤이 전달될 것이다) 데이터 바인딩을 수행할 수 있는 것이다.
DataGridColumn 클래스와 그 자식 클래스는 TableCell과 밀접한 관계를 가지고 있으며 데이터 바인딩에서도 중요한 역할을 수행함을 알 수 있을 것이다. 필요에 따라 DataGridColumn 클래스를 상속하여 커스텀 컬럼을 만들 수도 있다. 몇몇 필수적인 메쏘드와 프로퍼티를 구현하기만 하면 원하는 HTML을 렌더링하도록 구성이 가능할 것이다. 이에 대한 상세한 내용은 이 글의 범위에서 벗어나므로 생략하기로 한다.
그 외의 클래스들
지금까지 설명한 컨트롤과 클래스들 외에도 데이터그리드와 연관된 클래스들은 데이터그리드 클래스의 베이스 클래스인 BaseDataList 클래스, 데이터그리드의 각종 스타일에 대한 TableItemStyle 클래스, 페이징에 대한 추상화를 제공하는 PagedDataSource 클래스, DataGridItem과 DataGridColumn에 대한 컬렉션을 제공하는 DataGridItemCollection 클래스, DataGridColumnCollection 클래스 등의 클래스가 있다. 이들 클래스들은 데이터그리드가 작동하는데 직간접적으로 관여한다. 특히 BaseDataList 클래스는 데이터리스트 컨트롤과 데이터그리드 컨트롤에 대한 베이스 클래스로서 데이터바인딩을 지원하는 리스트 컨트롤의 공통적인 인터페이스와 구현을 제공한다.
데이터그리드 컨트롤에 대한 분석을 하고자 한다면 시작점은 BaseDataList가 돼야 할 것이다. PagedDataSource 클래스는 데이터그리드의 데이터소스 속성에 설정된 데이터 소스에 대한 페이징 뷰를 제공한다. 예를 들어 데이터소스가 30개의 레코드를 갖고 PageSize가 10인 상태에서 AllowPagaing이 True라면 PagedDataSource는 현재 페이지의 10개 레코드만을 반환하고 AllowPagaing이 False라면 현재 페이지에 관계 없이 전체 30개의 레코드를 반환한다. PagedDataSource 클래스의 이러한 데이터소스 추상화는 데이터그리드 컨트롤이 AllowPaging 속성에 관계없이 단일 코드 플로우(flow)를 갖도록 해준다. 그 외의 클래스는 데이터그리드의 외양을 제어하고 컬렉션을 구현하는 데 이용된다.
데이터그리드 제어 흐름
데이터그리드의 구조를 살펴봤으니 이제 제어의 흐름을 살펴보자. 데이터그리드도 역시 일반적인 웹 컨트롤의 일종이므로 웹 컨트롤의 일반 제어 흐름을 따른다. 웹 컨트롤의 일반적인 제어 흐름과 데이터그리드의 구체적인 작업은 <표 1>과 같다. 데이터그리드의 전체 제어 흐름을 설명하기에는 그 분량이 너무 많으므로 핵심적인 몇몇 사항과 주의해야 할 사항에 대해서만 언급하기로 한다.

"ASP.NET" 카테고리의 다른 글
- ASP.NET Execution Model (4)2006/07/30
- 풍성한 ASP.NET 개발환경의 이해 1 - 4 (0)2006/03/17
- 풍성한 ASP.NET 개발환경의 이해 1 - 3 (0)2006/03/17
- 풍성한 ASP.NET 개발환경의 이해 1 - 2 (0)2006/03/17
- 풍성한 ASP.NET 개발환경의 이해 1 - 1 (0)2006/03/17

수안이의 컴퓨터 연구실



Leave your greetings.