유경상 (ksyu@tysystems.com)
ASP.NET 정식 버전이 등장한지 1년여가 지났다. ASP.NET은 기존 버전이라 할 수 있는 ASP에 비해 매우 다른 접근 방식을 취하고 있다. 기존 ASP 4.0은 HTML 태그 사이사이에 ASP 코드가 삽입되어 있는 형태로서 CGI나 ISAPI에 비해 개발 생산성을 높여 준다는 장점을 등에 업고 성공했다. 시간이 지나감에 따라 ASP 코드와 HTML이 뒤범벅돼 있는 페이지가 양산되기 시작했고 이는 웹 사이트의 유지 보수와 가독성을 떨어뜨리는 요인으로 작용했다. ASP.NET은 새로운 모델을 제시했다. 소위 웹폼(WebForm) 모델은 웹 페이지를 VB 6.0과 같은 폼 디자인 형태로 개발을 가능하게 해줄 뿐더러 이벤트에 기반한 페이지 제어 모델을 제공한다. 웹폼 모델의 핵심은 ASP.NET의 System.Web.UI.Page 클래스와 다양한 웹 컨트롤이라고 할 수 있다.
웹 컨트롤은 ASP.NET을 처음 배우는 개발자에게 웹 프로그래밍이 쉽다는 느낌을 주지만 어느 정도 경험이 쌓이면 한계로 다가온다. 처음에는 다양한 기능을 제공하는 웹 컨트롤이 도움을 주는 듯 느끼지만 다양한 웹 컨트롤을 사용하다 보면 웹 컨트롤의 제약사항에 빠지기도 하고 무분별한 웹 컨트롤의 사용으로 인해 웹 사이트의 성능이 크게 떨어지는 것을 경험하곤 한다. 웹 컨트롤은 어떻게 사용하는가에 따라 ASP.NET 개발자에게 축복으로 다가오기도 하고 재앙으로 다가오기도 한다는 점을 명심하자.
대표 선수, 데이터그리드
ASP.NET에서 기본적으로 제공하는 웹 컨트롤 중 가장 다양하고 막강한 기능을 가진 컨트롤을 뽑으라면 단연 데이터그리드(DataGrid) 컨트롤을 꼽을 것이다. 데이터 바인딩은 물론이요, 페이징, 정렬, 편집, 추가, 삭제 등의 기능을 갖고 있다. ASP.NET을 처음 접하는 개발자는 데이터그리드의 기능에 놀라며 그 현란함에 감탄하기 마련이다. 그러나 막상 데이터그리드를 실제 사이트에 사용하려고 하면 다양한 문제에 부딪히곤 한다. 데이터그리드의 막강한 기능들은 그 대가가 있다. 첫째로 데이터그리드는 매우 큰 ViewState를 생산한다. 이는 웹 페이지가 생성하는 HTML의 크기가 커짐을 의미하며 이는 곧 웹 페이지의 처리 속도 저하를 가져온다. 그래서 ViewState를 disable시키면, 데이터그리드의 막강한 기능들인 페이징, 정렬 등의 기능은 사용할 수 없게 되어 버린다. 데이터그리드의 편집/추가/삭제 기능은 사실상 많이 사용되지 않기 때문에 차치하더라도 페이징과 정렬을 사용할 수 없게 되면 상당한 양의 코딩을 개발자가 추가로 해야 한다는 부담이 생기곤 한다.
데이터그리드 구조
왜 ViewState를 disable하면 데이터그리드의 기능들이 작동하지 않을까? 이 질문에 대답하기 위해서는 데이터그리드의 구조에 대해 이해할 필요가 있다. 데이터그리드의 구조가 다양한 기능으로 인해 매우 복잡한 것처럼 보이지만 알고 보면 그다지 복잡하다고 볼 수만은 없다. 텍스트 박스나 리스트 박스와 같은 단순 컨트롤의 경우 구조라고 할 것도 없이 간단하지만 데이터그리드는 여러 컨트롤로 구성된 합성 컨트롤(Composite Control)로서 컨트롤이 계층 구조를 이루고 있다. 데이터그리드의 컨트롤 계층 구조를 알아보는 가장 쉬운 방법은 페이지의 트레이스(Trace) 속성을 True로 설정하는 것이다. Trace가 활성화되면 <화면 1>과 같은 결과를 얻을 수 있으며 구조를 파악하는 데 도움이 된다. 데이터그리드의 일반적인 컨트롤 계층 구조는 <그림 1>과 같다.

<화면 1> ASP.NET 트레이스 기능으로 살펴본 데이터그리드 컨트롤 계층 구조
<그림 1>에서 주의할 사항은 이 그림이 컨트롤의 계층 구조를 나타내고 있다는 점이다. 컨트롤이라 함은 System.Web.UI.Control 클래스에서 파생된 웹 컨트롤을 의미하므로 <그림 1>의 구조는 데이터그리드를 구성하는 웹 컨트롤의 구조라는 것이다. 컨트롤이 아닌 클래스의 관점에서 보면 데이터그리드는 <그림 1>에 나타난 웹 컨트롤 클래스 외에도 DataGridColumn, BoundColumn 등의 컬럼 관련 클래스들, 데이터그리드의 외양에 많은 영향을 미치는 스타일 관련 클래스들과 관련이 있다. 컬럼 관련 클래스에 대해서는 조금 후에 언급하기로 하고 컨트롤 계층 구조에 대해 좀더 상세히 살펴보자.
데이터그리드 컨트롤의 자식 컨트롤은 DataGridTable 하나뿐이다(자손이 아닌 자식임에 유의). DataGridTable 컨트롤은 HTML 태그를 렌더링하는 컨트롤로서 데이터그리드에서만 사용되는 컨트롤이다. 이 컨트롤은 특별한 기능을 하지 않는다. 다만 DataGridItem 컨트롤에 대한 부모 역할을 수행하고 태그를 렌더링할 뿐이다. 데이터그리드를 구성하는 컨트롤 중에서 중요한 역할은 DataGridItem 컨트롤이 수행한다.

<그림1> 데이터그리드 컨트롤 계층 구조
DataGridItem 컨트롤과 TableCell 컨트롤
사실 DataGridItem과 TableCell을 컨트롤로 볼 것인가에 대해 필자는 약간 고민을 했다. 이들은 모두 독립적으로 사용될 수 없으며 항상 다른 컨트롤의 자식으로만 사용되므로 컨트롤보다는 객체 정도로 표현해야 하지 않을까 생각이 들었다. 하지만 이들은 공히 컨트롤 클래스에서 파생되고 웹 컨트롤의 생명 주기를 따르므로 컨트롤의 최소 요건을 모두 갖추었다고 볼 수 있으므로 컨트롤로 분류하기로 했다. 이에 대해 이의 있는 독자는 언제든지 필자에게 메일을 보내기 바란다.
DataGridItem 컨트롤은 TableRow 컨트롤에서 파생된 컨트롤로서 HTML 태그와 대응되는 컨트롤이다. DataGridItem 컨트롤 역시 데이터그리드를 위해서만 사용되며 데이터컨트롤의 헤더, 풋터(footer), 그리고 페이저를 나타내거나 데이터 아이템의 한 레코드와 일대일로 대응되는 개념을 갖는다. 데이터그리드는 AllowPaging 속성(property)에 의해 페이저를 위한 DataGridItem 생성을 결정한다. AllowPaging 속성이 False라면 페이저를 위한 DataGridItem은 생성되지 않는다. 반면 헤더 및 풋터를 위한 DataGridItem은 항상 생성된다. 이는 ShowHeder, ShowFooter 속성과는 무관하다. 데이터그리드의 ShowXXXX 속성이나 Visible 류의 속성은 컨트롤이 HTML 태그들을 생성하는 방법을 결정할 뿐이지 웹폼 내의 컨트롤 생성 여부를 결정하지 않음에 주의해야 한다. 예를 들어 AllowPaging 속성이 True이면 PagerStyle 속성과 관계없이 페이저를 위한 두 개의 DataGridItem 컨트롤이 생성된다.
DataGridItem 컨트롤은 자식 컨트롤로서 TableCell 컨트롤들을 가진다. DataGridItem의 ItemType에 따라 자식 TableCell 컨트롤의 갯수는 달라진다. 페이저는 하나의 TableCell 컨트롤만을 가지며 헤더/풋터, 아이템 등의 경우에는 컬럼의 갯수만큼 TableCell 컨트롤을 가진다. 여기서도 주의할 점은 웹 브라우저에 나타나는 컬럼 수와 TableCell 컨트롤의 갯수는 동일하지 않다는 점이다. 데이터그리드의 Columns 컬렉션이 나타내는 데이터그리드 컬럼들은 Visible 속성을 가지고 있다. 이 속성 역시 TableCell의 생성 여부를 좌우하지 않는다는 점을 명심해야 한다. 따라서 DataGridItem 컨트롤이 갖는 자식 TableCell 컨트롤의 갯수는 Columns 컬렉션이 보유하는 데이터그리드 컬럼 갯수와 AutoGenerateColumn 속성의 값 그리고 데이터소스(DataSource)의 컬럼 갯수와 연관이 있다.
TableCell 컨트롤은 HTML 태그에 대응되는 컨트롤로서 직접 데이터를 표시하거나 다른 컨트롤의 부모 역할을 한다. DataGridItem이 페이저라면 TableCell은 자식 컨트롤로서 다수의 LinkButton 컨트롤과 Literal 컨트롤을 갖으며 DataGridItem이 헤더이고 정렬이 enable되어 있다면 TableCell은 몇 개의 LinkButton 컨트롤을 자식 컨트롤로 보유하게 된다. TableCell이 어떤 자식 컨트롤을 갖는가는 DataGridItem이 어떤 종류인가에 영향을 받지만 해당 컬럼(DataGridColumn)이 어떤 컬럼인가 그리고 현재 DataGridItem이 편집 상태에 있는가에도 영향을 받는다. 대개의 경우 컬럼은 데이터바인딩을 수행하는 단순한 BoundColumn이다.
BoundColumn인 경우 TableCell 컨트롤은 편집 상태가 아닌 경우에는 자식 컨트롤을 갖지 않고 TableCell 컨트롤의 Text 속성에 데이터 값이 표현된다. 편집 상태라면 TableCell은 TextBox 컨트롤을 자식 컨트롤로 갖으며 이 컨트롤의 Text 속성에 데이터가 표시된다. 비슷하게 TableCell의 컬럼이 ButtonColumn 타입이라면 LinkButton 컨트롤 혹은 Button 컨트롤이 TableCell의 자식이 되며 데이터 역시 이 자식 컨트롤에 표시된다. 이외에도 TableCell의 컬럼이 TemplateColumn이라면 템플릿이 지정하는 서버 컨트롤이 TableCell의 자식으로 설정되며, 데이터바인딩 역시 템플릿이 지정하는 데이터바인딩 식에 의해 표현된다.
웹 컨트롤은 ASP.NET을 처음 배우는 개발자에게 웹 프로그래밍이 쉽다는 느낌을 주지만 어느 정도 경험이 쌓이면 한계로 다가온다. 웹 컨트롤은 어떻게 사용하는가에 따라 ASP.NET 개발자에게 축복으로 다가오기도 하고 재앙으로 다가오기도 한다는 점을 명심해야 할 것이다. 웹 컨트롤의 대표 선수로서 데이터그리드 컨트롤의 구조를 살펴보고 이 컨트롤의 문제점을 진단해 보자.
ASP.NET 정식 버전이 등장한지 1년여가 지났다. ASP.NET은 기존 버전이라 할 수 있는 ASP에 비해 매우 다른 접근 방식을 취하고 있다. 기존 ASP 4.0은 HTML 태그 사이사이에 ASP 코드가 삽입되어 있는 형태로서 CGI나 ISAPI에 비해 개발 생산성을 높여 준다는 장점을 등에 업고 성공했다. 시간이 지나감에 따라 ASP 코드와 HTML이 뒤범벅돼 있는 페이지가 양산되기 시작했고 이는 웹 사이트의 유지 보수와 가독성을 떨어뜨리는 요인으로 작용했다. ASP.NET은 새로운 모델을 제시했다. 소위 웹폼(WebForm) 모델은 웹 페이지를 VB 6.0과 같은 폼 디자인 형태로 개발을 가능하게 해줄 뿐더러 이벤트에 기반한 페이지 제어 모델을 제공한다. 웹폼 모델의 핵심은 ASP.NET의 System.Web.UI.Page 클래스와 다양한 웹 컨트롤이라고 할 수 있다.
웹 컨트롤은 ASP.NET을 처음 배우는 개발자에게 웹 프로그래밍이 쉽다는 느낌을 주지만 어느 정도 경험이 쌓이면 한계로 다가온다. 처음에는 다양한 기능을 제공하는 웹 컨트롤이 도움을 주는 듯 느끼지만 다양한 웹 컨트롤을 사용하다 보면 웹 컨트롤의 제약사항에 빠지기도 하고 무분별한 웹 컨트롤의 사용으로 인해 웹 사이트의 성능이 크게 떨어지는 것을 경험하곤 한다. 웹 컨트롤은 어떻게 사용하는가에 따라 ASP.NET 개발자에게 축복으로 다가오기도 하고 재앙으로 다가오기도 한다는 점을 명심하자.
대표 선수, 데이터그리드
ASP.NET에서 기본적으로 제공하는 웹 컨트롤 중 가장 다양하고 막강한 기능을 가진 컨트롤을 뽑으라면 단연 데이터그리드(DataGrid) 컨트롤을 꼽을 것이다. 데이터 바인딩은 물론이요, 페이징, 정렬, 편집, 추가, 삭제 등의 기능을 갖고 있다. ASP.NET을 처음 접하는 개발자는 데이터그리드의 기능에 놀라며 그 현란함에 감탄하기 마련이다. 그러나 막상 데이터그리드를 실제 사이트에 사용하려고 하면 다양한 문제에 부딪히곤 한다. 데이터그리드의 막강한 기능들은 그 대가가 있다. 첫째로 데이터그리드는 매우 큰 ViewState를 생산한다. 이는 웹 페이지가 생성하는 HTML의 크기가 커짐을 의미하며 이는 곧 웹 페이지의 처리 속도 저하를 가져온다. 그래서 ViewState를 disable시키면, 데이터그리드의 막강한 기능들인 페이징, 정렬 등의 기능은 사용할 수 없게 되어 버린다. 데이터그리드의 편집/추가/삭제 기능은 사실상 많이 사용되지 않기 때문에 차치하더라도 페이징과 정렬을 사용할 수 없게 되면 상당한 양의 코딩을 개발자가 추가로 해야 한다는 부담이 생기곤 한다.
데이터그리드 구조
왜 ViewState를 disable하면 데이터그리드의 기능들이 작동하지 않을까? 이 질문에 대답하기 위해서는 데이터그리드의 구조에 대해 이해할 필요가 있다. 데이터그리드의 구조가 다양한 기능으로 인해 매우 복잡한 것처럼 보이지만 알고 보면 그다지 복잡하다고 볼 수만은 없다. 텍스트 박스나 리스트 박스와 같은 단순 컨트롤의 경우 구조라고 할 것도 없이 간단하지만 데이터그리드는 여러 컨트롤로 구성된 합성 컨트롤(Composite Control)로서 컨트롤이 계층 구조를 이루고 있다. 데이터그리드의 컨트롤 계층 구조를 알아보는 가장 쉬운 방법은 페이지의 트레이스(Trace) 속성을 True로 설정하는 것이다. Trace가 활성화되면 <화면 1>과 같은 결과를 얻을 수 있으며 구조를 파악하는 데 도움이 된다. 데이터그리드의 일반적인 컨트롤 계층 구조는 <그림 1>과 같다.

<그림 1>에서 주의할 사항은 이 그림이 컨트롤의 계층 구조를 나타내고 있다는 점이다. 컨트롤이라 함은 System.Web.UI.Control 클래스에서 파생된 웹 컨트롤을 의미하므로 <그림 1>의 구조는 데이터그리드를 구성하는 웹 컨트롤의 구조라는 것이다. 컨트롤이 아닌 클래스의 관점에서 보면 데이터그리드는 <그림 1>에 나타난 웹 컨트롤 클래스 외에도 DataGridColumn, BoundColumn 등의 컬럼 관련 클래스들, 데이터그리드의 외양에 많은 영향을 미치는 스타일 관련 클래스들과 관련이 있다. 컬럼 관련 클래스에 대해서는 조금 후에 언급하기로 하고 컨트롤 계층 구조에 대해 좀더 상세히 살펴보자.
데이터그리드 컨트롤의 자식 컨트롤은 DataGridTable 하나뿐이다(자손이 아닌 자식임에 유의). DataGridTable 컨트롤은 HTML 태그를 렌더링하는 컨트롤로서 데이터그리드에서만 사용되는 컨트롤이다. 이 컨트롤은 특별한 기능을 하지 않는다. 다만 DataGridItem 컨트롤에 대한 부모 역할을 수행하고 태그를 렌더링할 뿐이다. 데이터그리드를 구성하는 컨트롤 중에서 중요한 역할은 DataGridItem 컨트롤이 수행한다.

DataGridItem 컨트롤과 TableCell 컨트롤
사실 DataGridItem과 TableCell을 컨트롤로 볼 것인가에 대해 필자는 약간 고민을 했다. 이들은 모두 독립적으로 사용될 수 없으며 항상 다른 컨트롤의 자식으로만 사용되므로 컨트롤보다는 객체 정도로 표현해야 하지 않을까 생각이 들었다. 하지만 이들은 공히 컨트롤 클래스에서 파생되고 웹 컨트롤의 생명 주기를 따르므로 컨트롤의 최소 요건을 모두 갖추었다고 볼 수 있으므로 컨트롤로 분류하기로 했다. 이에 대해 이의 있는 독자는 언제든지 필자에게 메일을 보내기 바란다.
DataGridItem 컨트롤은 TableRow 컨트롤에서 파생된 컨트롤로서 HTML 태그와 대응되는 컨트롤이다. DataGridItem 컨트롤 역시 데이터그리드를 위해서만 사용되며 데이터컨트롤의 헤더, 풋터(footer), 그리고 페이저를 나타내거나 데이터 아이템의 한 레코드와 일대일로 대응되는 개념을 갖는다. 데이터그리드는 AllowPaging 속성(property)에 의해 페이저를 위한 DataGridItem 생성을 결정한다. AllowPaging 속성이 False라면 페이저를 위한 DataGridItem은 생성되지 않는다. 반면 헤더 및 풋터를 위한 DataGridItem은 항상 생성된다. 이는 ShowHeder, ShowFooter 속성과는 무관하다. 데이터그리드의 ShowXXXX 속성이나 Visible 류의 속성은 컨트롤이 HTML 태그들을 생성하는 방법을 결정할 뿐이지 웹폼 내의 컨트롤 생성 여부를 결정하지 않음에 주의해야 한다. 예를 들어 AllowPaging 속성이 True이면 PagerStyle 속성과 관계없이 페이저를 위한 두 개의 DataGridItem 컨트롤이 생성된다.
DataGridItem 컨트롤은 자식 컨트롤로서 TableCell 컨트롤들을 가진다. DataGridItem의 ItemType에 따라 자식 TableCell 컨트롤의 갯수는 달라진다. 페이저는 하나의 TableCell 컨트롤만을 가지며 헤더/풋터, 아이템 등의 경우에는 컬럼의 갯수만큼 TableCell 컨트롤을 가진다. 여기서도 주의할 점은 웹 브라우저에 나타나는 컬럼 수와 TableCell 컨트롤의 갯수는 동일하지 않다는 점이다. 데이터그리드의 Columns 컬렉션이 나타내는 데이터그리드 컬럼들은 Visible 속성을 가지고 있다. 이 속성 역시 TableCell의 생성 여부를 좌우하지 않는다는 점을 명심해야 한다. 따라서 DataGridItem 컨트롤이 갖는 자식 TableCell 컨트롤의 갯수는 Columns 컬렉션이 보유하는 데이터그리드 컬럼 갯수와 AutoGenerateColumn 속성의 값 그리고 데이터소스(DataSource)의 컬럼 갯수와 연관이 있다.
TableCell 컨트롤은 HTML 태그에 대응되는 컨트롤로서 직접 데이터를 표시하거나 다른 컨트롤의 부모 역할을 한다. DataGridItem이 페이저라면 TableCell은 자식 컨트롤로서 다수의 LinkButton 컨트롤과 Literal 컨트롤을 갖으며 DataGridItem이 헤더이고 정렬이 enable되어 있다면 TableCell은 몇 개의 LinkButton 컨트롤을 자식 컨트롤로 보유하게 된다. TableCell이 어떤 자식 컨트롤을 갖는가는 DataGridItem이 어떤 종류인가에 영향을 받지만 해당 컬럼(DataGridColumn)이 어떤 컬럼인가 그리고 현재 DataGridItem이 편집 상태에 있는가에도 영향을 받는다. 대개의 경우 컬럼은 데이터바인딩을 수행하는 단순한 BoundColumn이다.
BoundColumn인 경우 TableCell 컨트롤은 편집 상태가 아닌 경우에는 자식 컨트롤을 갖지 않고 TableCell 컨트롤의 Text 속성에 데이터 값이 표현된다. 편집 상태라면 TableCell은 TextBox 컨트롤을 자식 컨트롤로 갖으며 이 컨트롤의 Text 속성에 데이터가 표시된다. 비슷하게 TableCell의 컬럼이 ButtonColumn 타입이라면 LinkButton 컨트롤 혹은 Button 컨트롤이 TableCell의 자식이 되며 데이터 역시 이 자식 컨트롤에 표시된다. 이외에도 TableCell의 컬럼이 TemplateColumn이라면 템플릿이 지정하는 서버 컨트롤이 TableCell의 자식으로 설정되며, 데이터바인딩 역시 템플릿이 지정하는 데이터바인딩 식에 의해 표현된다.
"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.