대상 : ASP.NET의 기본적인 컨트롤 사용법을 뗀 이들.
선수지식 : ADO.NET 기본 지식.
DataList 컨트롤도 Repeater 컨트롤과 마찬가지로 템플릿을 기반으로 데이터를 출력합니다. Repeater 컨트롤의 발전형이기 때문에 템플릿을 사용하는 방법 등 기본적인 사용법은 기존 Repeater 컨트롤의 경우와 동일하죠. 하지만, 이는 Repeater 컨트롤보다 다양한 기능을 갖는 컨트롤입니다. Repeater 컨트롤과는 달리 데이터의 선택 및 변경을 위한 추가적인 템플릿이 제공되어 읽어들인 데이터에 수정 및 삭제하는 작업이 가능하구요. 각각의 템플릿에 대해 스타일을 지정할 수도 있답니다. 버튼 등의 컨트롤을 DataList 컨트롤 내부에 올려서 이벤트를 처리하는 것도 그리 어렵지 않고 말이죠. 호홋
이러한 장점들로 인해 이 컨트롤은 간단한 표 형태의 출력이 아닌 조금은 복잡한 형태의 출력을 요구할 경우에 유용하다고 볼 수 있습니다. 특히, 쇼핑몰에서 상품을 진열할 경우에 아주 유용하죠. 고로, 반드시 사용법을 알아두는 것이 좋습니다. ^^
이 컨트롤의 단점이라면 페이징을 구현하기가 쉽지 않다는 것인데... 기쁜 소식은 이 강좌가 끝나고 이어질 강좌...에서 그러한 페이징을 매우 쉽게 가능하게 해주는 PageingHelper 를 여러분에게 소개해 드릴 것이라는 것이지요... 일단은 기대해 보세요 ^^
레이아웃
Repeater 컨트롤은 출력과 관계해서는 그 어떠한 태그도 컨트롤이 만들지 않았었다는 것을 기억하세요? 즉, 출력과 관계된 코드는 개발자가 모두 하드 코딩으로 작성해야만 했었다는 이야기랍니다. 하지만, DataList 의 경우는 이 부분이 조금 달라요. DataList는 기본적으로 각각의 템플릿에 대해서 테이블(<TABLE>) 태그를 자동으로 생성해 주거든요. 즉, 다음 그림과 같이 기본 테이블 태그 내에 자동으로 각각의 템플릿 코드들이 끼워져 출력되는 형태로 나타난다는 것이랍니다.

DataList에서는 이를 RepeatLayout 이라 부르는데요. RepeatLayout의 값으로는 Table과 Flow를 사용할 수 있습니다. 기본 값은 위에서 확인한 것처럼 Table이구요. 이 레이아웃의 형태를 Flow로 바꿀 수도 있지만, 바꿀 경우 테이블 태그를 대신하여 태그가 각각의 템플릿을 둘러싸는 형태가 되며, 브라우저 중에는 <span> 태그를 이해하지 못하는 브라우저도 있으므로, Flow 레이아웃을 사용하는 것은 그리 추천적이지 못합니다. 해서, 대부분의 경우 기본 레이아웃인 Table를 사용하는 것이 권장되지요.
예제를 통해서 하나씩 확인해 나가 보도록 해요. 먼저, 새로운 웹 폼 페이지를 여러분의 프로젝트에 하나 추가하도록 해요. 페이지의 이름은 DataListEx1.aspx 라고 주도록 하구요. 페이지를 생성하였으면, 웹 폼 위에 하나의 DataList를 다음 그림과 같이 드래그 앤 드롭으로 올려놓도록 합니다.

다음으로는, 코드 비하인드 페이지에 데이터를 바인딩하는 코드를 작성하세요.
private void Page_Load(object sender, System.EventArgs e) { if(!IsPostBack) BindDataList(); } private void BindDataList() { string connectStr = "Server=(local); database=Pubs; user id=sa"; SqlConnection Con = new SqlConnection(connectStr); SqlDataAdapter Adap= new SqlDataAdapter("Select Top5 * from titles", Con); DataSet ds = new DataSet(); Adap.Fill(ds, "titles"); DataList1.DataSource = ds.Tables["titles"]; DataList1.DataBind(); } |
Repeater 컨트롤에서 사용했던 코드와 동일한 코드이니 특별히 설명할만한 것은 없어 보이네요. 단지, 실제로 데이터를 DataList에 바인드 하는 부분을 별도의 함수(BindDataList)로 분리해 두었다는 것과, 데이터 바인딩 시 Page의 IsPostBack 속성 값을 검사하여, 페이지가 처음 로드되는 경우에만 바인드를 한다는 점만이 다릅니다. 그 중 특히 IsPostBack 속성의 사용은 매우 주목할 필요가 있어요. 일단, 바운드 컨트롤에 로드된 모든 데이터는 기본적으로 VIEWSTATE를 통해서 그 값이 유지되므로, 이 후 페이지가 포스트백 될 때마다 데이터베이스로부터 데이터를 가져와서 바인드를 해줄 필요가 없거든요. 페이지가 처음 로드되는 경우에만 로드해주는 것이 효율적이며, 그렇게 하는 것이 성능상에도 큰 도움이 됩니다. 물론, 그 저장되는 데이터가 너무나도 대량이라면 한 번 더 생각해 보아야 할 것이긴 하지만요.
이제, 마지막으로 DataList의 템플릿을 꾸밀 차례입니다. 다음과 같이 템플릿을 구성해 보도록 하세요.
<asp:DataList id="DataList1" runat="server" GridLines="Both" Width="400"> <HeaderTemplate> <b>이 달의 추천도서</b> </HeaderTemplate> <ItemTemplate> <div> <img src='images/Title-<%# DataBinder.Eval(Container.DataItem, "title_id")%>.gif' hspace="10"/> 제목 : <b><%# DataBinder.Eval(Container.DataItem, "title") %></b><br /> 가격 : <%# DataBinder.Eval(Container.DataItem, "price", "$ {0}") %><br /> <%# DataBinder.Eval(Container.DataItem, "notes") %> </div> </ItemTemplate> <FooterTemplate> ⓒCopyright 2002 Taeyo.com All rights reserved. </FooterTemplate> </asp:DataList> |
구성된 코드를 보면, HeaderTemplate 쪽에는 간단한 문장만이 놓여진다는 것을 알 수 있고, FooterTemplate 쪽에는 저작권 정보가 놓여진다는 것을 알 수 있습니다. 중요한 것은 ItemTemplate 인데, 이번의 경우는 이미지 태그가 있는 것으로 보아 해당 책의 이미지와 함께 책의 정보를 출력하려 함을 알 수 있을 겁니다. 그렇다면, 여러분에게도 이러한 이미지가 있어야 할 터인데, 여러분이 .NET Framework과 함께 QuickStart 샘플들을 설치했다면, 이미 이러한 이미지가 여러분의 하드상에 저장되어져 있을 것예요. 진짭니다. 일반적인 경우 그 이미지가 들어있는 디렉터리의 경로는
C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\QuickStart\aspplus\images
입니다. 그 디렉터리 안에는 수많은 이미지가 있는데, 그 중 Title- 라는 접두어로 시작하는 이미지가 바로 Pubs 데이터베이스의 titles 테이블을 위한 책의 이미지들이지요. 총 18개의 이미지가 있을텐데, 그것을 복사해서 현재 프로젝트의 Images 폴더로 모두 가져오도록 하세요. ^^;
< p> 코드를 보면 이미지의 소스경로를 src='images/Title-<%# DataBinder.Eval(Container.DataItem, "title_id")%>.gif'
라고 주고 있습니다. 실제로 이미지들의 이름이 Title-이라는 접두어와 함께 책의 title_id 로 구성되어져 있기 때문에 소스에서도 그렇게 이름을 지정한 것이이지요.
좋습니다. 좋구요. 이제 여러분의 머리속에는 대략적인 출력 모습이 연상될 겁니다.(아니라구요? 헉??) 그렇든, 아니든, 이제는 페이지를 컴파일하고 실행해 보도록 하자구요. 예상한대로 결과가 출력되었나요?

사실, 여기서 image 태그의 Src의 값을 작은 따옴표로 둘러주고 있다는 점은 중요합니다. 일반적으로 HTML 태그의 값은 큰 따옴표(“)를 사용하여 값을 둘러주고는 하는데, 이번의 경우는 작은 따옴표를 사용하고 있지요. 사실, 큰 따옴표를 사용하든지, 작은 따옴표를 사용하든지 그것은 큰 문제가 되지 않아요. HTML 태그에서는 짝만 맞게 사용한다면 작은 따옴표던 큰 따옴표던 어떤 것을 사용해도 무방하기 때문이지요. 그런데, 여기서는 왜 작은 따옴표를 사용한 것일까요? 이유는 간단합니다. Src 내의 값으로 지정된 코드 중에 큰 따옴표가 이미 존재하고 있기 때문이지요. 바인딩 표현식 내부에 말입니다. 고로, 여러분이 src 의 값을 다음과 같이 큰 따옴표로 둘러준다면 src="images/Title-<%# DataBinder.Eval(Container.DataItem, "title_id")%>.gif" Src 의 실제 값은 큰 따옴표가 사용되는 중간 부분까지로 인식됩니다. 다음처럼 말이죠. src="images/Title-<%# DataBinder.Eval(Container.DataItem, " 그러므로, 이는 구문에 이상이 있는 것이기에 문제가 발생할 소지가 있어요. 해서, 위의 경우는 반드시 작은 따옴표로 둘러 주어서 이러한 문제를 미연에 방지해야 할 것입니다. 작은 따옴표로 바꾸지 않고, 큰 따옴표를 그대로 둔 경우에도 사실 실행(run)에는 문제가 없지만, 웹 폼 디자이너로 변환하고자 할 경우 변환이 불가능하다는 메시지를 받게 될 것입니다. 의심된다면 한번 해보세요 ^^ |
GridLines 속성
결과가 제대로 출력되었다면, 다시금 HTML 소스부로 돌아와서 DataList 컨트롤의 시작 코드를 살펴보도록 해요. 그 안에는 수 많은 속성들을 사용할 수 있지만, 예제에서는 그 중 GridLines 라는 속성을 사용하고 있습니다.
<asp:DataList id="DataList1" runat="server" GridLines= "Both" Width="400">
GridLines 속성은 출력되는 테이블의 테두리를 어떤 형태로 나타나게 할 것인지를 지정하는 속성으로, 이 속성에 사용할 수 있는 값으로는 Both, Horizontal, None, Vertical 이 있습니다. Both는 가로 및 세로 테두리를 모두 나타나게 하는 것이고, Horizontal은 가로 테두리만을, Vertical은 세로 테두리만을 나타나게 하는 것이랍니다. None은 테두리를 나타나게 하지 않는 것이고 말입니다. 예제의 경우는 이 값으로 Both를 사용하고 있기에 결과 테이블의 테두리가 가로, 세로 모두 출력될 것임을 예상할 수 있을 겁니다.
그렇다면, DataList 컨트롤에 사용할 수 있는 또 다른 속성들에는 어떤 것들이 있는지 궁금하지 않나요? 좋아요. 그러하다면 우선 그들을 한번 알아보도록 해요.
속성 | 설명 |
CellPadding | 셀 사이의 간격(pixels). RepeatLayout이 Table일 경우만 적용된다 |
CellSpacing | 셀과 셀 내의 컨텐트 와의 사이 간격(pixels). RepeatLayout이 Table일 경우만 적용된다 |
DataKeyField | 바인드된 데이터 원본에서 기본 키로 사용할 필드 |
DataSource | 바인딩할 데이터 원본 |
GridLines | 테두리의 출력 형태. 사용 가능한 값 : None, Horizontal, Vertical, Both |
RepeatColumns | 아이템을 출력하는 데 사용할 컬럼의 수 |
RepeatDirection | 아이템이 출력되는 방향. Vertical은 위에서 아래로 출력하며, Horizontal은 왼쪽에서 오른쪽으로 출력한다 |
RepeatLayout | DataList의 출력 레이아웃. 기본값은 Table. 사용 가능한 값 : Flow, Table |
ShowFooter | Footer를 보이게 할 지의 여부 |
ShowHeader | Header를 보이게 할 지의 여부 |
속성들 중에 눈에 가장 먼저 들어오는 것은 어떤 것인가요? 저의 경우는 RepeatDirection 속성이었습니다. 출력되는 결과가 상,하로 뿐 아니라 좌,우로도 배치가 가능하다는 인상을 주기 때문이지요. 그렇습니다. 이 속성을 사용하면, 기존(ASP)에는 출력하기에 상당히 피곤한 부분이었던 가로 출력이 손 쉬어지게 됩니다. 그렇다면, 이 속성을 직접 사용해서 얼마나 멋진 결과가 나오는지를 한번 살펴보도록 해요.
RepeatColumns, RepeatDirection
HTML 소스 중에서 DataList 컨트롤의 시작 코드를 다음과 같이 변경해 보도록 하세요.
<asp:DataList id="DataList1" runat="server" GridLines="Both"
Width="800" RepeatColumns="2" RepeatDirection="Vertical"> |
|
그리고, 페이지를 다시금 실행해 보세요.

예상한대로 출력 결과가 가로로 출력되는 것을 볼 수 있습니다. 이는 List 컨트롤에서 다루어 본 것과 유사한 결과이며, 기존(ASP)의 기술로는 상당히 어려웠던 부분 중에 하나이지요. 하지만, .NET에서는 DataList를 사용하여 매우 간단하게 이러한 출력을 만들어 낼 수 있습니다. (그리드 관련 컨트롤 중 DataList 만이 이 기능을 지원합니다. Repeater이나 DataGrid는 이 기능을 지원하지 않거든요 ^^;)
Template의 Style
DataList는 또한 템플릿의 스타일을 지정할 수 있도록 해 줍니다. DataList에서는 템플릿 하나 하나가 사실상 테이블의 셀(<td>)을 의미하기에 그 셀의 배경색이나 전경색, 너비 등을 설정할 수 있는 방법을 제공하는 것이죠. 그렇다면, 제공되는 스타일에는 어떠한 것들이 있을까요? 당연하게도 각각의 템플릿에 대해서 다음과 같은 각각의 스타일이 제공된 답니다.
템플릿 | 설명 |
HeaderStyle | HeaderTemplate의 스타일을 설정한다 |
FooterStyle | FooterTemplate의 스타일을 설정한다 |
ItemStyle | ItemTemplate의 스타일을 설정한다 |
AlternatingItemStyle | AlternatingItemTemplate의 스타일을 설정한다 |
SeparatorStyle | SeparatorTemplate의 스타일을 설정한다 |
EditItemStyle | EditItemTemplate의 스타일을 설정한다 |
SelectedItemStyle | SelectedItemTemplate의 스타일을 설정한다 |
그리고, 각각의 스타일에서 설정할 수 있는 속성들에는 다음과 같은 것들이 있어요. 다음 표는 그러한 속성들을 역할에 따라 분류해서 나타내 본 것입니다.
속 | 설명 |
BackColor | 배경색 설정 |
BorderColor, BorderStyle, BorderWidth | 테두리와 관련된 설정 |
Font-Bold, Font-Italic, Font-Name, Font-Names, Font-Overline, Font-Size, Font-Strikeout, Font-Underline, ForeColor | 폰트와 관계된 설정 |
Height, Width | 사이즈와 관련된 설정 |
HorizontalAlign, VerticalAlign | 정렬과 관련된 설정 |
각각의 속성들의 역할은 이름만으로도 충분히 이해할 수 있을 것입니다. 좋습니다. 이제 이러한 템플릿 스타일을 추가로 작성하여 DataList의 출력을 좀 더 아름답게 바꾸어 보도록 해요. 다음과 같은 코드를 <DataList> 태그 구역 안에 추가해 보도록 하세요.(이 페이지는 제 책에서 제공하는 소스 파일들 중에서 DataListEx1plus.aspx라는 이름으로 제공되고 있습니다. 제 책의 소스는 위의 태오 사이트 메뉴중에서 BOOKS를 클릭하시면 얻을 수 있어요 ^^)
<asp:DataList id="DataList1" runat="server" GridLines="Both" Width="800" RepeatColumns="2" RepeatDirection="Vertical">
<HeaderStyle BackColor="slategray" ForeColor="white"></HeaderStyle> <FooterStyle BackColor="khaki" ForeColor="blue"></FooterStyle> <ItemStyle BackColor="white"></ItemStyle> <AlternatingItemStyle BackColor="#dddddd"></AlternatingItemStyle> |
|
대단한 코드들은 아닙니다. 각각의 템플릿에 배경색과 전경색을 주고 있을 뿐이니 말입니다. 위와 같이 스타일을 지정하였다면, 이제 페이지를 컴파일하고 실행해 보도록 하세요. 다음과 같이 지정된 스타일이 반영된 결과를 볼 수 있을 것입니다.

재미있는 것은 AlternatingItemStyle인데요. 코드 중에는 AlternatingItemTemplate이 없음에도 불구하고, AlternatingItemStyle 스타일이 결과에 반영되는데, 이는 짝수 번째로 출력되는 아이템은 내부적으로 AlternatingItemTemplate으로 취급되며, 그에 적용되는 스타일로 AlternatingItemStyle이 사용되기 때문이랍니다.
EditItemTemplate과 ItemCommand
또한, DataList 컨트롤은 Repeater 컨트롤이 제공하는 템플릿들 외에 2개의 템플릿을 더 제공해 주고 있습니다. 일단 그들을 살펴보면, 그들은 다음과 같아요.
템플 | 설명 |
EditItemTemplate | 편집 모드로 설정되어질 때 출력되는 템플릿. 이 템플릿에는 보통 TextBox 컨트롤과 같은 편집 컨트롤이 포함되어지게 됩니다. 이 템플릿은 일반적인 경우는 출력되지 않으며, 항목의 순서 번호를 DataList 컨트롤의 EditItemIndex에 설정할 경우에 해당 항목에 대한 EditItemTemplate이 출력되어집니다. |
SelectedItemTemplate | 사용자가 DataList 컨트롤에서 항목을 선택했을 때 렌더링되는 템플릿. 이 템플릿은 일반적인 경우는 출력되지 않으며, 항목의 순서 번호를 DataList 컨트롤의 SelectedIndex에 설정할 경우 해당 항목의 SelectedItemTemplate이 출력되어 집니다. |
위의 설명을 읽어보면 일단!! 이러한 템플릿들은 기본적으로는 출력이 되지 않는다는 것을 알 수 있습니다. 설명을 다시금 잘 읽어보면, 어떤 이벤트에 의해서 DataList의 EditItemIndex나 SelectedIndex의 값이 설정되어야만 이러한 템플릿이 사용되어진다는 것을 알 수 있을 것입니다. 그렇다면, 이제 템플릿에 버튼 컨트롤을 하나 추가해 보도록 해요. 그리고, 버튼이 클릭될 경우, 선택된 셀의 템플릿을 SelectedItemTemplate으로 바꾸어 출력하도록 만들어 보려 합니다.
그런데, 그 전에 먼저 알아두어야 할 것이 있어요. 여러분이 DataList에 버튼 컨트롤을 올리게 되면, 그 버튼은 클릭되었을 경우, 버튼 자신의 Click 이벤트를 발생하는 것이 아니라, DataList의 ItemCommand 라는 이벤트를 발생시키게 된다는 점입니다. 이를 이벤트 버블링이라고 하는데요, 이는 자식 컨트롤이 포함 계층 구조의 상위로 이벤트를 전달할 수 있게 하는 기술이랍니다. Repeater, DataList, DataGrid 모두 이벤트 버블링을 지원하구요, 그로 인해 컨트롤의 템플릿 내에서 발생한 이벤트는 모두 ItemCommand 이벤트로 버블된답니다.
말이 좀 어렵나요? 간단하게 말씀드리면 말입니다... 이러한 그리드 컨트롤의 템플릿 내의 버튼이 눌릴 경우의 처리는 기존과는 달리 그리드 컨트롤의 ItemCommand 에서 해야한다는 말이랍니다. 말로 설명하니까 조금 어렵게 느껴지지만 코드로 마주하게 되면 그리 어려운 내용이 아니예요. 그렇다면, 예제로써 이해를 해보도록 해요.
우선 여러분의 ItemTemplate를 다음과 같이 변경해 보세요
<ItemTemplate> <DIV> <IMG hspace="10" align="left" Src='http://localhost/quickstart/ASPPlus/images/Title- <%# DataBinder.Eval(Container.DataItem, "title_id") %>.gif'> 제목 : <B><%# DataBinder.Eval(Container.DataItem, "title") %></B><BR> 가격 : <%# DataBinder.Eval(Container.DataItem, "price", "$ {0}") %><BR> <%# DataBinder.Eval(Container.DataItem, "notes") %>
<p><asp:Button Runat="server" Text="선택"></asp:Button></p> | </DIV> </ItemTemplate> |
그리고, 다음과 같이 SelectedItemStyle도 추가하도록 해요
<asp:DataList id="DataList1" runat="server" GridLines="Both" Width="800" RepeatColumns="2" RepeatDirection="Vertical"> <HeaderStyle BackColor="slategray" ForeColor="white"></HeaderStyle> <FooterStyle BackColor="khaki" ForeColor="blue"></FooterStyle> <ItemStyle BackColor="white"></ItemStyle> <AlternatingItemStyle BackColor="#dddddd"></AlternatingItemStyle> <SelectedItemStyle BackColor="yellow"></SelectedItemStyle> |
이제, 웹 폼 디자인 모드로 화면을 변환하여, 웹 폼에서 DataList 컨트롤을 선택하도록 해요. 웹 폼은 다음과 같은 모습을 하고 있을 것입니다.

그리고, [속성 창]에서 번개 모양의 버튼을 클릭한 뒤, 출력되는 이벤트들 중에서 ItemCommand를 선택하고, 우측 칸에서 더블 클릭을 합니다.

그러면, 코드 비하인드 페이지로 이동하고, 자동으로 DataList1_ItemCommand 이벤트 처리기가 생성되어져 있을 것입니다. 이미 언급했듯이, 이는 DataList 내의 그 어떠한 버튼 컨트롤이든지 눌렸을 경우 발생하는 이벤트입니다. 이 곳에 다음과 같은 코드를 작성해 보도록 하세요.
private void DataList1_ItemCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e) { DataList1.SelectedIndex = e.Item.ItemIndex; BindDataList(); } |
다 되었다면, 이제 페이지를 컴파일하고 실행해보도록 해요.

재미있게도 결과 화면에서 버튼을 클릭하면, 버튼이 클릭된 셀의 배경색이 노란색으로 변하는 것을 볼 수 있을 겁니다. 즉, SelectedItemStyle이 적용된다는 것이죠. 버튼이 눌렸을 경우 수행되는 DataList1_ItemCommand 내에서 우리가 DataList1.SelectedIndex를 사용자가 현재 선택한 아이템의 값으로 지정해 주었기 때문에 이렇게 SelectedItemStyle이 적용되는 거랍니다. 코드로 지정해주지 않으면, 자동으로 SelectedItemStyle이 반영되지는 않는다는 점을 기억하세요.
ItemCommand 이벤트는 인자로써 이벤트와 관련된 데이터를 포함하는 DataListCommandEventArgs 개체를 받아들이구요. 이 개체는 다음과 같은 정보들을 제공합니다.
속성 | 설명 |
CommandArgument | 명령에 대한 인수 |
CommandName | 명령의 이름 |
CommandSource | 명령의 원본(여기서는 버튼 컨트롤) |
Item | DataList 컨트롤에서 명령 원본(여기서는 버튼 컨트롤)이 포함된 항목 |
DataList1.SelectedIndex = e.Item.ItemIndex;
BindDataList();
고로, 위의 코드에서의 e.Item.ItemIndex는 현재 DataList 컨트롤에 존재하는 아이템들 중 현재 선택된 아이템의 인덱스 값을 의미하는 것이며, 그 값을 DataList의 SelectedIndex 속성에 지정하고 있다는 것을 알 수 있습니다. 그리고, BindDataList()라는 함수를 호출하고 있는데, 이는 알고 있듯이 데이터를 DataList에 바인드하는 코드입니다.
위의 설명은 너무 간단했던 것 같네요. 좋습니다. 그렇다면, 다시 풀어서 설명해 보도록 하겠습니다..
DataList의 어떤 항목(템플릿)을 선택된 것으로 나타내기 위해서는 우선 그 항목이 몇 번째 항목인지를 DataList에게 알려주어야 하는데, 그를 위해 사용되는 속성은 DataList.SelectedIndex입니다. 이 속성에다가 선택된 항목의 번호를 알려주고, 다시 바인드를 수행해 주면 해당 항목은 위의 그림에서 보이는 것처럼 선택된 항목으로써 출력되는 것이지요. 좋아요. 그렇다면, 이제 궁금한 것은 현재 선택된 항목을 어떻게 알아낼 수 있느냐인데요. 답은 간단합니다. 그것은 ItemCommad 이벤트의 두 번째 인자로 넘어오는 개체를 통해서 알아낼 수 있거든요. 위의 코드에서의 e가 바로 그것인데, 이 개체는 내부적으로 Item 이라고 하는 속성 개체를 제공하며, 그 개체는 현재 이벤트를 발생시킨(버튼이 클릭된) 항목 자체를 의미하는 개체입니다. 그리고, 그 Item 개체의 ItemIndex 속성을 통해서 현재 선택된 항목의 순서 번호값을 얻어올 수 있게 되는 것이지요.
해서, DataList의 특정 항목을 선택된 것으로 지정하기 위해서는, 먼저 DataList 컨트롤의 SelectedIndex 값을 e 개체의 Item.ItemIndex 값을 사용하여 적절히 지정해 준 다음, 데이터를 다시금 바인딩 해 주면 되는 것입니다. ASP.NET이 알아서 바인딩을 해주지는 않으니 말입니다. 이는 공식과 같으므로 반드시 기억해 두도록 하세요.
특정 아이템을 선택된 것으로 나타내는 것은 그리 어렵지 않았네요. 그렇다면, 특정 아이템을 편집하려면 어떻게 해야 할까요?
EditItemTemplate
여러분은 이미 DataList가 제공하는 템플릿으로 EditItemTemplate 이 있다는 것을 알고 있을 겁니다. 이 템플릿은 여러분이 해당 템플릿 아이템을 변경하고자 할 경우 대체되는 템플릿으로, 기본적으로는 출력에 포함되어지지 않으며, DataList의 EditItemIndex 값이 지정될 경우에만 해당 아이템의 EditItemTemplate이 출력되어지게 됩니다. EditItemTemplate은 대부분 TextBox와 같은 컨트롤로 구성되어 출력 값을 변경할 수 있는 쉬운 방법을 제공하는데요, 복잡한 변경을 위해서보다는 간단한 변경을 위해서 사용될 수 있는 상당히 유용한 기능입니다. 관리자 툴 같은 것을 제작할 경우에는 이 방법이 상당히 유용한 편이죠. 좋아요. 그럼 이제 한번 해보도록 해요.
먼저, 여러분의 HTML에 EditItemTemplate을 추가해 보도록 해요. 다음과 같은 코드를 여러분의 DataList 코드 구역 내에 삽입하면 됩니다.
<EditItemTemplate> <DIV> <IMG hspace="10" align="left" src='http://localhost/quickstart/ASPPlus/images/Title- <%# DataBinder.Eval(Container.DataItem, "title_id") %>.gif' > 제목 : <asp:TextBox Runat="server" BorderStyle="Groove" width="250" ID="title" NAME="title" Text='<%# DataBinder.Eval(Container.DataItem, "title") %>'> </asp:TextBox> <BR> 가격 : <asp:TextBox Runat="server" BorderStyle="Groove" ID="price" NAME=" price " Text='<%# DataBinder.Eval(Container.DataItem, "price") %>'></asp:TextBox> <BR> <asp:TextBox Runat="server" BorderStyle="Groove" TextMode="MultiLine" Rows="5" Width="300" Text='<%# DataBinder.Eval(Container.DataItem, "notes") %>' ID="notes" NAME=" notes "></asp:TextBox> </DIV> </EditItemTemplate> |
코드를 통해서 EditItemTemplate 의 출력모습을 예상해 볼 수 있으신가요? 이 템플릿은 책의 제목, 가격, 설명의 값이 TextBox에 들어있다는 것을 제외하면 기존과 크게 다른 점이 없습니다. 이 코드에 의한 대략적인 출력 모습은 다음과 같아요.

좋습니다. 이제 ItemTemplate에 다음과 같이 버튼 컨트롤을 하나 더 추가하도록 합시당. 아이템을 선택할 경우와 마찬가지로 어떤 아이템을 변경하려 한다면, 버튼 컨트롤과 같은 것으로 이벤트를 발생시켜 줘야 할 것이기 때문이지요. 코드를 작성하면서 주목해야 할 점은 새로이 추가하는 [변경] 버튼 컨트롤의 CommandName의 값이 edit 라는 점입니다. 나중에 이 값이 중요한 키워드임을 알게 될 것이니, 기억하고 있기 바래요.
<ItemTemplate> <DIV> <IMG hspace="10" align="left" Src='http://localhost/quickstart/ASPPlus/images/Title- <%# DataBinder.Eval(Container.DataItem, "title_id") %>.gif'> 제목 : <B><%# DataBinder.Eval(Container.DataItem, "title") %></B><BR> 가격 : <%# DataBinder.Eval(Container.DataItem, "price", "$ {0}") %><BR> <%# DataBinder.Eval(Container.DataItem, "notes") %> <p><asp:Button Runat="server" Text="선택"></asp:Button>
<asp:Button Runat="server" Text="변경" CommandName="edit"></asp:Button> | </p> </DIV> </ItemTemplate> |
이제 페이지를 컴파일하고, 결과를 확인해 보도록 하세요. 결과 페이지가 출력되면 [변경] 버튼을 눌러서 특정 아이템의 출력이 EditItemTemplate으로 대체되어 나타나는지 확인해 보시구요. 아직은 여러분의 기대대로 출력되지 않을 것 같네요.

[변경] 버튼을 클릭해도 [선택] 버튼을 클릭했을 경우와 동일한 결과만이 나오고 있죠? 왜 안 바뀌는 것일까요? 이유는 간단합니다. EditItemTemplate도 SelectedItemTemplate과 마찬가지로 그냥은 바뀌지 않거든요. 클릭 이벤트 시에 코드로써 어떤 아이템이 EditItemTemplate으로 대체되어야 하는지를 알려주어야만 한답니다. DataList 컨트롤 내의 모든 버튼들이 눌릴 경우는 ItemCommand 이벤트가 호출된다고 이야기했었죠? 고로, 이러한 처리도 그 이벤트 처리기 안에 작성해야 할 것입니다. 다음과 같이 말이죠.
private void DataList1_ItemCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e) { if(e.CommandName == "edit") DataList1.EditItemIndex = e.Item.ItemIndex; else DataList1.SelectedIndex = e.Item.ItemIndex; BindDataList(); } |
각각의 버튼의 CommandName은 ItemCommand 이벤트의 두 번째 인자인 DataListCommandEventArgs 개체를 통해서 넘어옵니다. 이는 이전에 표로써 이미 같이 살펴보았었죠.(진짜입니다. 위로 올라가서 확인해 보세요) 해서, 만일 현재 클릭된 버튼의 CommandName이 "edit" 라면 DataList1.EditItemIndex에 현재 선택된 아이템의 ItemIndex를 지정합니다. 이러한 지정으로 현재의 지정된 템플릿 아이템이 EditItemTemplate으로 대체되는 것이죠. 이러한 이유로 [변경] 버튼 컨트롤의 CommandName 속성의 값을 우리가 "edit"라고 미리 지정해 두었던 것입니다. [선택] 버튼과 구별할 수 있도록 하기 위해서 말입니다.
그렇다면, 이제 페이지를 컴파일하고 다시금 실행해 보도록 하세요. 우리의 예상대로 잘 동작하는 것을 확인할 수 있을 겁니다. 물론, 변경된 데이터를 실제로 처리하는 부분은 아직 작성하지 않았기에 그 부분은 동작하지 않을 것이지만 말입니다.(이 소스는 다운로드한 파일들 중에서 DataListEx1plus2.aspx라는 이름으로 존재하고 있습니다)

다음 강좌에서는 Command 관련 이벤트들에 대해서 이야기하는 것을 시작으로 DataList 컨트롤의 두 번째 이야기를 진행해 보도록 하겠습니다.