관리 메뉴

IT 쟁이

리피터 컨트롤 - 출처 - 태요 .NET 본문

ASP.NET/서버컨트롤

리피터 컨트롤 - 출처 - 태요 .NET

클라인STR 2008. 1. 17. 21:41

Taeyo's ASP.NET

   강좌 최초 작성일 : 2003년 02월 18일
   강좌 최종 수정일 : 2003년 02월 19일

   강좌 읽음 수 : 43811 회

   작성자 : Taeyo(김 태영)
   편집자 : Taeyo(김 태영)

   강좌 제목 : Repeater Control (1)

강좌 전 태오의 잡담>

GOGOGO ^^;


대상 : ASP.NET의 기본적인 컨트롤 사용법을 뗀 이들.
선수지식 : ADO.NET 기본 지식.

Repeater 컨트롤들은 템플릿을 기반으로 하여 데이터의 바인드 목록을 만드는 컨트롤입니다. 가장 단순한 형태의 바운드 컨트롤이기에 사실 다루기가 그리 어렵지 않은 컨트롤이기도 하지요. 이 컨트롤은 기본적으로 제공하는 레이아웃이나 스타일이 전혀 없으므로, 화면 출력과 관계된 모든 코드를 개발자가 직접 작성해야만 한다는 단점(?)이 있습니다.

만일, 여러분이 MS의 위저드(마법사)와 같은 자동 생성도구를 좋아한다면 이 컨트롤은 그다지 맘에 들지 않을 겁니다. 컨트롤이 보유한 자체기능은 그리 많지 않은데다가, 대부분의 기능을 개발자가 하드 코딩으로 작성해야 하기 때문이죠.

다음은 Repeater 컨트롤의 기본 포맷입니다.

<asp:Repeater id="컨트롤의 ID" runat=server>
    <HeaderTemplate>
        Header template HTML
    </HeaderTemplate>
    <ItemTemplate>
        Item template HTML
    </ItemTemplate>
    <AlternatingItemTemplate>
        Alternating item template HTML
    </AlternatingItemTemplate>
    <SeparatorTemplate>
        Separator template HTML
    </SeparatorTemplate>
    <FooterTemplate>
        Footer template HTML
    </FooterTemplate>
<asp:Repeater>

위의 코드에서도 볼 수 있다시피, 이 컨트롤은 내부에 여러 종류의 Template 태그들을 가집니다.

그렇다면, 그러한 템플릿에는 어떠한 것들이 있는지 알아보는 시간을 가져보도록 하겠습니다. 템플릿의 의미나 목적이 지금 당장은 명확하게 느껴지지 않을 수도 있지만, 일단은 부담없이 살펴보도록 하세요. 구체적인 사용법은 예제를 통해서 익히게 될 것이니까요. ^^;

템플릿 설명
<HeaderTemplate> 바인드된 데이터가 렌더링되기 전에 먼저 출력되는 요소로, 주로 머리말 정보를 위해 사용되는 템플릿이다. 이 템플릿에는 데이터 바인드를 할 수 없다
<ItemTemplate> 데이터 원본의 각 행에 대해 한 번 렌더링되는 템플릿이다. 어떤 데이터를 어떤 형태로 표현할 것인지는 여러분이 바인드 표현식을 사용하여 템플릿 내에 직접 작성해 주어야 한다. 이는 템플릿 구성 시 필수적으로 필요한 템플릿이다.
<AlternatingItemTemplate> ItemTemplate과 기능적으로는 같지만, 출력되는 항목을 건너뛰면서 적용되는 템플릿이다. 즉, 출력되는 2,4,6 번째 항목을 위해서 사용할 수 있는 템플릿이다.
<FooterTemplate> HeaderTemplate과는 반대로 꼬리말 정보를 위해서 사용되는 템플릿이다. 역시 데이터 바인드가 불가능하다.
<SeparatorTemplate> 출력되는 각각의 항목 사이에 렌더링되는 템플릿이다. 이 템플릿 안에서도 데이터 바인드는 불가능하다.

템플릿의 역할이 잘 이해되지 않는다면 다음 그림을 살펴보도록 하세요. 이는 컨트롤에 의해 <Table>이 출력되었을 경우, 각각의 템플릿의 역할을 도식적으로 나타낸 그림이랍니다.

이 그림으로도 이해가 잘 가지 않는다면 다음 그림은 어떻습니까? 이것은 실제로 데이터가 출력된 테이블을 대상으로 템플릿의 역할을 나타내 본 그림이랍니다.

각각의 템플릿에 대한 실제적인 사용방법은 예제를 통해서 이해하도록 하구요.. 이번에는 Repeater 컨트롤의 중요한 속성과 메서드, 이벤트에 대해서 알아보겠습니다.

속성 설명
DataMember 컨트롤에 바인딩할 DataSource 내의 특정 테이블.
DataSource 컨트롤에 바인드할 데이터 원본.
메서드 설명
DataBind 실제로 데이터를 서버 컨트롤로 바인딩하는 메서드
이벤트 설명
ItemCommand 컨트롤 구역 내에서 버튼이 클릭되는 경우 발생하는 이벤트.
ItemCreated Repeater의 컨트롤에 항목을 만드는 경우 발생하는 이벤트
ItemDataBound Repeater의 항목을 바인딩 한 다음 페이지에 렌더링하기 전에 발생하는 이벤트

물론, 위의 목록이 Repeater 컨트롤의 전체 속성과 메서드는 아닙니다. 단지, 자주 사용되는 기능들만을 정리한 것이죠. Repeater 컨트롤에 데이터를 바인드하기 위해서는 적어도 위의 속성 중 DataSource 속성에 대해서는 값을 설정해 주어야 하구요. 그리고 난 다음, DataBind() 메서드를 통해서 실제적인 바인딩을 수행해야만 합니다. 이 둘의 지정은 필수에 가깝다는 것을 기억하세요.

정리하자면, Repeater 컨트롤을 사용하여 데이터를 바인딩하고자 하는 경우에는 다음과 같은 단계를 따르는 것이 좋습니다.

1. 웹 폼 위에 Repeater 컨트롤을 하나 올려놓는다.
2. 바인드할 데이터 원본을 계획한다.
    이는 대부분의 경우 데이터베이스에서 SELECT 질의로 가져온 뷰 테이블이 될 것이다.
    그 다음, 코드 비하인드 페이지의 코드에서 데이터 원본을 Repeater 컨트롤의 DataSource 속성으로
    묶어주고, DataBind() 메서드를 호출하도록 한다.
3. 폼 디자이너의 HTML 모드에서 Repeater 컨트롤의 템플릿을 작성한다.

그렇다면, 위의 순서에 따라 직접 예제를 통하여 Repeater 컨트롤을 다루어 보겠습니다. 여러분의 프로젝트에 RepeaterEx1.aspx 라는 이름의 웹 폼 페이지를 하나 추가하고, 다음 그림과 같이 Repeater 컨트롤을 [도구상자]로부터 드래그 앤 드롭하여 웹 폼 위에 올려놓아 보세요..

이제 코드 비하인드 페이지로 이동하여 Page_Load 이벤트 처리기에 다음과 같은 코드를 작성해 주세요.

private void Page_Load(object sender, System.EventArgs e)
{
    string connectStr = "Server=(local); database=Pubs; user id=sa";
    //위의 데이터베이스 연결 문자열은 여러분의 상황에 맞게 구성해 주세요
    SqlConnection Con = new SqlConnection(connectStr);
    SqlDataAdapter Adap = new SqlDataAdapter("Select Top 5 * from titles", Con);

    DataSet ds = new DataSet();
    Adap.Fill(ds, "titles");

    Repeater1.DataSource = ds;
    Repeater1.DataMember = "titles";
    Repeater1.DataBind();
}

이 코드는 Pubs 데이터베이스 내 titles 테이블의 상위 5개의 레코드를 DataSet으로 가져와서, Repeater 컨트롤의 DataSource 속성으로 묶고, DataBind()를 수행하는 코드입니다. (ADO.NET을 공부하셨다면 이미 알고 있겠지만, SQL Server .NET 데이터 공급자를 사용하기 위해서는 using System.Data.SqlClient; 를 네임스페이스 참조 구역에 추가해 주어야 합니다. 잊었다면 지금 코딩하시기 바랍니다)

위의 소스는 여러분이 ADO.NET의 기초편을 공부하셨다면 그다지 어렵지 않을 것입니다. (참고로, ADO.NET 강좌는 다음 링크에서 조금이나마 확인해 볼 수 있습니다)

깜찍이님의 ADO.NET 강좌

굳이 반복해서 설명한다면, 코드는 먼저 데이터베이스 연결 문자열을 가지고, Connection 개체를 생성하고 있으며, 다음으로 DataAdapter 개체를 생성하면서, 내부적으로 "Select Top 5 * from titles"라는 질의를 수행하는 Command 개체를 생성하고 Connection 개체와 연결합니다. 그리고 난 다음, DataAdapter의 수행결과를 담기 위한 DataSet 개체를 하나 생성하고 있으며, DataAdapter 개체의 Fill 메서드를 통해서 Select 질의의 수행결과를 "titles" 라는 이름으로 DataSet에 담고 있죠. 그러므로, 현재 시점에서 DataSet은 titles 라는 이름의 하나의 뷰 테이블을 메모리상에 보유하게 되는 것입니다. (어렵나요?)

참고!!

만일, 여러분의 열화와 같은 요청이 이어진다면, ADO.NET에 대한 강좌도 진행해 보도록 하겠습니다. 하지만, 제가 실제로 진행하고 싶은 강좌는 계층형 게시판 만들기나, 쇼핑몰 만들기 등의 실전 프로그램 템플릿이기에 가급적이면 ADO.NET과 관계된 부분은 여러분이 별도로 공부를 진행해 보시기를 추천합니다. 물론, 실전 템플릿을 진행하면서도 ADO.NET을 자주 거론할 것이기는 합니다만 말입죠~~~

물론, ADO.NET에 대해서는 태오의 이번 ASP.NET 책을 구입해서 보시면 매우 잘 나와있습니다!!!! 결혼 후 얍삽해진 태오. 이제 책에 대한 광고도 서슴치 않는 뻔뻔함을 보이고 있습니다. KEKE~~

강추!! Taeyo's ASP.NET v1.0 with C# .......       -_-a

필요한 데이터를 메모리로 가져왔으므로 이제 필요한 작업은 그 데이터를 Repeater 컨트롤에 바인드 하는 것입니다. 이어지는 소스가 바로 그러한 코드이며, 이번 예제에서 가장 주목할만한 부분이지요.. 주목 주목!!

Repeater1.DataSource = ds;
Repeater1.DataMember = "titles";
Repeater1.DataBind();

먼저, Repeater 컨트롤의 DataSource 속성으로써 DataSet을 지정하고 있으며, DataMember 속성값으로는 DataSet 내에 존재하는 뷰 테이블 중 "titles"를 지정하고 있습니다. 현재 DataSet 내에는 오직 "titles" 테이블 하나만이 존재하고 있다고 해도 이는 반드시 지정해 주어야 합니다.

그리고, DataBind() 메서드의 호출이 이어집니다. 실제적으로 데이터를 바인드하는 시점이 바로 DataBind() 메서드가 호출되는 때이므로, 이 코드가 가장 중요한 코드라고 볼 수 있습니당...

사실, 위의 코드에서 Repeater 개체의 DataMember 속성을 반드시 사용해야 하는 것은 아니긴 합니다. 다음과 같이 DataSource 속성을 조금 더 구체적으로 작성한다면 말이죠.

Repeater1.DataSource = ds.Tables["titles"];
Repeater1.DataBind();

이제 코드 비하인드 페이지의 작성도 모두 끝났네요. 페이지를 실행할 경우, 실제로 이 코드들은 수행될 것이며, Repeater 컨트롤에 결과 데이터들이 멋지게 바인드될 것임을 여러분은 확신할 수 있을 것입니다. 바뜨 그러나!! 당황스럽게도 화면에는 그 어떠한 데이터도 출력되지 않을 것입니다. 크핫핫!

"아유~~ 재섭떠.. 웃길라구 괜히 장난치지 말구 어서 이유나 말해줘. 너의 유치한 개그는 하나도 잼업떠~"

"-_-+ ........ 음... 그런..거 .. 였.. 군..요"

말씀드리기 싫어지고 있지만, 그래도 맘 착한 제가 참아서 말씀드리면... 이유는 각각의 데이터들이 어떻게 출력되어야 하는지를 아직 정의해 놓은 것이 없기 때문입니다. 바인드하는 코드만으로 실제 데이터가 출력되는 것은 아니거든요. 완전하게 바인드된 결과를 얻기 위해서는 데이터가 어떤 형태로 출력되어야 할 지를 미리 정의해 두어야만 한답니다.

그렇다면, 이를 위해 해야 할 작업은 무엇일까요? 그렇습니다. 바로 템플릿을 작성하는 것입니다. 다시금 웹 폼 디자이너로 돌아오도록 해요. 그리고, 웹 폼 디자이너에 놓여진 Repeater 컨트롤에 나타나고 있는 문장을 한번 읽어보세요. 템플릿을 작성하기 위해서 해야할 일이 무엇인지를 컨트롤이 친절하게 알려주고 있을 겁니다.

그렇다면, 이제 컨트롤이 해달라는 대로 HTML 모드로 전환하여 다음과 같이 Repeater 컨트롤의 템플릿 코드들을 작성해 보도록 해요~.

<asp:Repeater id="Repeater1" runat="server">
    <HeaderTemplate>
        <p><b>오늘의 신간</b></p>
    </HeaderTemplate>
    <ItemTemplate>
        <p>
            제목 : <%# ((DataRowView)Container.DataItem)["title"] %><br />
            가격 : <%# ((DataRowView)Container.DataItem)["Price"] %>
        </p>
    </ItemTemplate>
    <SeparatorTemplate>
        <hr align="left" size="1" width="500">
    </SeparatorTemplate>
    <FooterTemplate>
        <hr>
    </FooterTemplate>
</asp:Repeater>

Repeater 코드 내부에 여러 개의 템플릿들을 작성해 보았는데, 그들은 각각 HeaderTemplate, ItemTemplate, SeparatorTemplate, FooterTemplate 입니다. HeaderTemplate은 데이터 바인드가 불가능하며, 출력 시 가장 상단에 단 한번 출력되는 템플릿이구요. 템플릿 중 ItemTemplate이 메인이 되는 템플릿인데, 이는 DataSource로 지정된 뷰 테이블의 레코드 수 만큼 반복되면서 데이터 바인드를 수행하는 템플릿입니다. ItemTemplate 내부에는 다음과 같은 바인딩 표현식이 놓여져 있는 것을 볼 수 있어요.

<p>
제목 : <%# ((DataRowView)Container.DataItem)["title"] %><br />
가격 : <%# ((DataRowView)Container.DataItem)["Price"] %>
</p>

즉, 각각의 행을 반복하면서 그 행의 title 컬럼과 price 컬럼의 값을 출력하는 코드인 겁니다. 물론, 이 코드는 Eval 메서드를 사용하는 다음과 같은 방법으로 대신할 수도 있어요.

<p>
제목 : <%# DataBinder.Eval(Container.DataItem, "title") %> <br />
가격 : <%# DataBinder.Eval(Container.DataItem, "Price") %>
</p>

SeparatorTemplate은 각각의 항목 사이에 놓여지는 템플릿으로 데이터 바인딩이 불가능한 템플릿입니다. 대부분의 경우, 이 템플릿 안에는 구분자로 사용할만한 것들이 놓여지죠. 예를 들면, 수평 라인 같은 것들 말입니다.

반면, FooterTemplate은 출력시 가장 밑 단에 단 한번 놓여지는 템플릿이며, 역시 데이터 바인딩은 불가능합니다. 코드를 모두 작성했다면, 페이지를 컴파일하고 실행해 보도록 하세요.

엇? 그렇습니다. 예외가 발생할 것입니다. 어째서 이런 일이?? 태오가 하라는 대로 하면 언제나 문제 투성이??? -_-+

사실 예외의 이유는 현재 우리가 웹 폼 페이지에서 사용하고 있는 다음과 같은 형 변환 코드 때문니다.

((DataRowView)Container.DataItem)["title"]

DataRowView 라는 타입을 현재의 웹 폼 페이지에서는 이해할 수가 없기 때문에 예외가 발생한 것입죠. 고로, 이 문제를 해결하려면, 현재의 웹 폼 페이지에 DataRowView 라는 개체를 가지고 있는 System.Data라는 네임스페이스를 임포트 해 주어야 한답니다.

약간은 의아스러울 수도 있을 것이라 생각해요. 그도 그럴 것이 System.Data 네임스페이스는 이미 코드 비하인드 페이지에 추가되어 있는 상태이니깐 말이죠. 하지만, 웹 폼 페이지와 코드 비하인드 페이지는 분리된 페이지라는 점을 기억하세요. 우리는 현재 코드 비하인드 페이지가 아닌 웹 폼 페이지내에서 DataRowView 라는 데이터 타입을 사용하려 하고 있습나다. 그러므로, 웹 폼 페이지에 직접 참조를 추가해 주어야 하는 것입니다.

HTML 코드 중 <%@Page %> 지시자 구역 다음으로 System.Data 네임스페이스를 참조하는 다음과 같은 코드를 추가하도록 하세요.

<%@ Page language="c#" Codebehind="RepeaterEx1.aspx.cs" AutoEventWireup="false" Inherits="TaeyoAspNet.RepeaterEx1" %>
<%@ Import NameSpace="System.Data" %>
...

물론, 여러분이 DataRowView로 형 변환하여 출력하는 방법 대신에 Eval 메서드를 사용하는 방법을 선택했다면 이와 같은 부가적인 작업은 필요치 않습니다. 어쩌면, 그러한 그러한 이유로 많은 개발자들이 Eval 메서드를 사용하여 바인드하는 방법을 선호하는 것 같기도 합니다.(Eval 메서드를 사용하는 방법은 다음 시간에 알아볼 겁니다요~~~)

어쨌든 이제, 다시금 컴파일 하고 실행해 보도록 해요. 이번에는 다음과 같이 제대로 된 결과를 얻을 수 있을 겁니당~

그리고, 결과에서 템플릿이 각각 적용된 부분을 표시하면 다음 그림과 같아요.

Repeater 컨트롤의 템플릿 사용법이 조금씩 이해가 되기 시작할 것입니다. (아니라면.. 서운한 걸요~)

템플릿이라고 하는 것은 결국 출력 결과의 일부를 구성하는 조각들인 것입니다. HeaderTemplate 및 FooterTemplate은 전체 출력 결과의 윗 단과 밑 단에 각각 한 번씩만 출력되는 구역을 의미하며, ItemTemplate은 모든 출력 행에 적용되는 구역, SeparatorTemplate은 각각의 항목 사이사이를 출력하는 역할을 담당하는 것이죠.

이 사실을 잘 기억해 두어야 합니다. 모든 바운드 컨트롤들이 템플릿을 사용하니 말입니다!!

Comments