Programming/.NET
GridView는 Table의 전체 Row를 Grid에 뿌리지만 DetailsView 컨트롤은 한번에 하나의 레코드에 해당하는 데이터만을 볼 수 있게 합니다. Table의 Row를 하나씩 표시하면서 데이터의 추가, 삭제, 변경또한 가능한 컨트롤입니다.

DetailsView 컨트롤의 사용은 어렵지 않으며 다른 데이터 컨트롤과 마찬가지로 데이터소스를 지정해 주기만 하면 기본적인 기능을 바로 수행할 수 있습니다.
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:new_connection %>" SelectCommand="SELECT * FROM [Person].[PersonPhone]"></asp:SqlDataSource>
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="425px" DataSourceID="SqlDataSource1"></asp:DetailsView>
보시는 바와같이 DetailsView 컨트롤은 데이터소스컨트롤에서 반환하는 데이터중 하나의 레코드에 해당하는 데이터만을 출력합니다.

▶ <그림 1-1>

DetailsView 는 데이터 소스의 쿼리결과 반환되는 데이터항목중 가장 처음것만을 표시하게 되는데 모든 데이터 항목을 하나씩 순환해 보려면 AllowPaging 속성을 true로 설정하여 페이징기능을 부여하면 됩니다.
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="425px" DataSourceID="SqlDataSource1" AllowPaging="true"></asp:DetailsView>
또한 GridView 처럼 PagerSettings- 속성을 통해 페이징이 구현되는 부분에 대한 스타일을 재정의 하는것도 가능합니다.

 표시항목 수정

GridView와 마찬가지로 해당 Row의 열전체를 표시하는 DetailsView 컨트롤은 동작방식을 수정하여 특정 열(Column)에 대한 데이터만 따로 표시할 수 있도록 지정할 수 있습니다.
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="425px" DataSourceID="SqlDataSource1" AllowPaging="true" AutoGenerateRows="false">
    <Fields>
        <asp:BoundField ReadOnly="True" HeaderText="BusinessEntityID" DataField="BusinessEntityID" Visible="false" />
        <asp:BoundField HeaderText="PhoneNumber" DataField="PhoneNumber" />
        <asp:BoundField HeaderText="PhoneNumberTypeID" DataField="PhoneNumberTypeID" />
        <asp:BoundField HeaderText="ModifiedDate" DataField="ModifiedDate" />
    </Fields>
</asp:DetailsView>
먼저 AutoGenerateRows 속성을 false 로 지정하여 자동적으로 데이터표시항목이 생성되는걸 막고 Fields 하위의 BoundField 객체를 사용해 표시할 열값을 일일이 지정해 주면 됩니다.

 GridView 와 연동하기

사실 DetailsView 컨트롤은 단독적으로 쓰이는 경우가 거의 없고 다른 데이터 컨트롤과 연동되어 특정 데이터에 대한 상세조회용도로 자주 사용됩니다. 여기서 말하는 연동가능한 컨트롤중에는 GridView 가 가장 대표적인 컨트롤이라 할 수 있겠습니다.

이런 경우를 생각해 보겠습니다. GridView에 표시된 데이터 항목에서 원하는 Row를 선택하는 경우 해당 Row에 대한 상세정보가 다시 DetailsView에 출력되는 경우입니다. 이런 시나리오를 구현하기 위해서는 다음과 같이 GirdView 컨트롤과 GridView 컨트롤 전용의 데이터소스 컨트롤을 배치해야 합니다.
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:new_connection %>" SelectCommand="SELECT * FROM [Person].[Person]"></asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server" DataSourceId="SqlDataSource1" AutoGenerateSelectButton="True" AllowPaging="True" DataKeyNames="BusinessEntityID"><SelectedRowStyle BackColor="AliceBlue" /></asp:GridView>
SqlDataSource 컨트롤의 Select 를 수정하여 Person.Person 테이블의 데이터를 가져오도록 하고 GridView에서 테이블로 표시합니다. 이때 GridView와 DetailsView 컨트롤 사이에 데이터를 가져오는 연결고리키로 DataKeyNames 속성을 지정합니다. 또한 GridView 컨트롤에서 선택항목을 구분하기 위해 SelectedRowStyle 을 사용하였습니다.
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:new_connection %>" SelectCommand="SELECT * FROM [Person].[PersonPhone]" FilterExpression="BusinessEntityID = '{0}'">
    <FilterParameters>
        <asp:ControlParameter Name="BusinessEntityID" ControlId="GridView1" PropertyName="SelectedValue" />
    </FilterParameters>
</asp:SqlDataSource>
<asp:DetailsView ID="DetailsView1" runat="server" DataSourceId="SqlDataSource2" AutoGenerateRows="True"></asp:DetailsView>
보시는 바와 같이 SqlDataSource 컨트롤은 GridView와 DetailsView 용도로 따로 생성합니다. SqlDataSource2 컨트롤에서는 FilterExpression 속성을 사용하여 [Person].[PersonPhone] 테이블에서 BusinessEntityID 에 주어지는 값에 해당하는 데이터만 가져오도록 하였습니다. 여기서 파라메터값은 ControlParameter 객체를 통해 GridView1 컨트롤에서 선택한 값중 BusinessEntityID 값이 주어지도록 지정되었습니다.


참고로 파라메터 지정에서 기존에 사용한 SelectParameters 는 SQL 쿼리단에서 Where 절로 추가가 가능하도록 하여 애초부터 파라메터에 해당하는 데이터만 가져오도록 제한된 데이터를 가져오게 됩니다. 데이터 자체가 제한된 데이터다 보니 다른 조건의 데이터가 필요한 경우 다시 데이터소스 컨트롤을 통해 데이터서버로 부터 새로운 데이터를 가져와야 하는 단점이 존재합니다.

반면 FilterParameters 를 사용하면 우선 데이터소스에서 모든 데이터를 가져와 서버의 메모리에 적재한 뒤 그 안에서 필터링을 적용하여 해당하는 데이터만을 표시하도록 합니다. 처음부터 모든 데이터를 가져와야 한다는 부담때문에 초기실행지연과 메모리소모에 대한 단점이 존재하지만 위 상황과 같이 선택항목마다 다른 내용을 빈번하게 보여줘야 하는 경우 메모리상에 존재하는 데이터만을 대상으로 필터링하게 되므로 데이터소스로 부터 서버에 원하는 데이터를 다시 조회해야 하는 경우가 불필요 하게 됩니다.

SelectParameters 나 FilterParameters 는 서로 장단점이 존재하므로 개발하고자 하는 환경에 맞게 적절히 골라 사용하시면 됩니다.

 데이터 추가/수정/삭제

DetailsView 를 이용하여 데이터를 추가/삭제/변경 하기 위해서는 DetailsView 컨트롤에 관련 기능을 하는 버튼(링크)을 생성하고 해당 DetailsView 의 데이터 소스 컨트롤에 실제 데이터처리를 위한 쿼리구문을 설정하기만 하면 됩니다.

예를 들어 데이터 추가에 대한 기능을 부여하고자 한다면 우선 DetailsView 에 AutoGenerateInsertButton 속성을 추가한뒤
<asp:DetailsView ID="DetailsView1" runat="server" DataSourceId="SqlDataSource2" AutoGenerateRows="True" AutoGenerateInsertButton="true"></asp:DetailsView>
데이터 소스 컨트롤에 InsertCommand 속성으로 데이터를 Insert 하는 쿼리구문을 지정합니다.
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:new_connection %>" SelectCommand="SELECT * FROM [Person].[PersonPhone]" FilterExpression="BusinessEntityID = '{0}'" InsertCommand="INSERT INTO [Person].[PersonPhone] VALUES(@BusinessEntityID, @PhoneNumber, @PhoneNumberTypeID, @ModifiedDate)">
    <FilterParameters>
        <asp:ControlParameter Name="BusinessEntityID" ControlId="GridView1" PropertyName="SelectedValue" />
    </FilterParameters>
</asp:SqlDataSource>
그러면 DetailsView 컨트롤 에는 'New' 라는 새로운 필드가 생기고


이 필드의 링크를 클릭하면 DB에 레코드를 추가할 수 있게 됩니다.


데이터를 삭제하거나 수정하는 경우도 위와 같은 순서로 설정하면 됩니다. 아래 <코드4-1>은 Insert, Update, Delete 의 모든 기능이 설정된 상태를 나타내고 있습니다.
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:new_connection %>" SelectCommand="SELECT * FROM [Person].[PersonPhone]" FilterExpression="BusinessEntityID = '{0}'" InsertCommand="INSERT INTO [Person].[PersonPhone] VALUES(@BusinessEntityID, @PhoneNumber, @PhoneNumberTypeID, @ModifiedDate)" DeleteCommand="DELETE FROM [Person].[PersonPhone] WHERE ([BusinessEntityID] = @BusinessEntityID)" UpdateCommand="UPDATE [Person].[PersonPhone] SET [PhoneNumber] = @PhoneNumber, [PhoneNumberTypeID] = @PhoneNumberTypeID, [ModifiedDate] = @ModifiedDate WHERE [BusinessEntityID] = @BusinessEntityID">
    <FilterParameters>
        <asp:ControlParameter Name="BusinessEntityID" ControlId="GridView1" PropertyName="SelectedValue" />
    </FilterParameters>
</asp:SqlDataSource>
<asp:DetailsView ID="DetailsView1" runat="server" DataSourceId="SqlDataSource2" AutoGenerateRows="True" DataKeyNames="BusinessEntityID" AutoGenerateInsertButton="true" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true"></asp:DetailsView>
▶ <코드 4-1>
1 0