다음을 통해 공유


DataList 또는 반복기 컨트롤에서 데이터 정렬(VB)

스콧 미첼

PDF 다운로드

이 자습서에서는 데이터 목록 및 반복기에서 정렬 지원을 포함하는 방법뿐만 아니라 데이터를 페이징하고 정렬할 수 있는 DataList 또는 Repeater를 생성하는 방법을 살펴보겠습니다.

소개

이전 자습서에서는 DataList에 페이징 지원을 추가하는 방법을 검토했습니다. 개체를 반환하는 클래스(GetProductsAsPagedDataSource)에 ProductsBLL 새 메서드를 PagedDataSource 만들었습니다. DataList 또는 Repeater에 바인딩된 경우 DataList 또는 Repeater는 요청된 데이터 페이지만 표시합니다. 이 기술은 GridView, DetailsView 및 FormView 컨트롤에서 내부적으로 기본 제공 페이징 기능을 제공하는 데 사용되는 것과 유사합니다.

페이징 지원을 제공하는 것 외에도 GridView에는 기본 정렬 지원도 포함됩니다. DataList와 Repeater는 기본 제공 정렬 기능을 제공하지 않습니다. 그러나 정렬 기능은 약간의 코드로 추가할 수 있습니다. 이 자습서에서는 데이터 목록 및 반복기에서 정렬 지원을 포함하는 방법뿐만 아니라 데이터를 페이징하고 정렬할 수 있는 DataList 또는 Repeater를 생성하는 방법을 살펴보겠습니다.

정렬 검토

페이징 및 정렬 보고서 데이터 자습서에서 볼 수 있듯이 GridView 컨트롤은 기본 정렬 지원을 제공합니다. 각 GridView 필드에는 데이터를 정렬할 데이터 필드를 나타내는 연결된 SortExpression필드가 있을 수 있습니다. GridView의 AllowSorting 속성이 설정된 true경우 속성 값이 있는 SortExpression 각 GridView 필드에는 해당 헤더가 LinkButton으로 렌더링됩니다. 사용자가 특정 GridView 필드의 헤더를 클릭하면 포스트백이 발생하고 클릭한 필드의 SortExpression정렬에 따라 데이터가 정렬됩니다.

GridView 컨트롤에는 SortExpression 데이터가 정렬된 GridView 필드의 저장 SortExpression 속성도 있습니다. SortDirection 또한 속성은 데이터를 오름차순 또는 내림차순으로 정렬할지 여부를 나타냅니다(사용자가 특정 GridView 필드의 헤더 링크를 두 번 연속으로 클릭하면 정렬 순서가 전환됨).

GridView가 데이터 원본 제어에 바인딩되면 해당 컨트롤과 SortDirection 속성을 데이터 원본 제어에 적용 SortExpression 합니다. 데이터 원본 컨트롤은 데이터를 검색한 다음 제공된 SortExpression 속성과 SortDirection 속성에 따라 정렬합니다. 데이터를 정렬한 후 데이터 원본 컨트롤은 GridView로 반환합니다.

DataList 또는 Repeater 컨트롤을 사용하여 이 기능을 복제하려면 다음을 수행해야 합니다.

  • 정렬 인터페이스 만들기
  • 정렬 기준으로 정렬할 데이터 필드와 오름차순 또는 내림차순으로 정렬할지 여부를 기억하세요.
  • ObjectDataSource에 특정 데이터 필드를 기준으로 데이터를 정렬하도록 지시합니다.

3단계와 4단계에서 이 세 가지 작업을 살펴보겠습니다. 그런 다음, 데이터 목록 또는 반복기에서 페이징 및 정렬 지원을 모두 포함하는 방법을 살펴보겠습니다.

2단계: 반복기에서 제품 표시

정렬 관련 기능을 구현하는 것에 대해 걱정하기 전에 먼저 Repeater 컨트롤에 제품을 나열해 보겠습니다. 먼저 폴더에서 Sorting.aspx PagingSortingDataListRepeater 페이지를 엽니다. 웹 페이지에 Repeater 컨트롤을 추가하고 해당 ID 속성을 .로 SortableProducts설정합니다. Repeater의 스마트 태그에서 명명된 ProductsDataSource 새 ObjectDataSource를 만들고 클래스의 GetProducts() 메서드에서 ProductsBLL 데이터를 검색하도록 구성합니다. INSERT, UPDATE 및 DELETE 탭의 드롭다운 목록에서 (없음) 옵션을 선택합니다.

ObjectDataSource를 만들고 GetProductsAsPagedDataSource() 메서드를 사용하도록 구성

그림 1: ObjectDataSource를 만들고 메서드를 사용하도록 GetProductsAsPagedDataSource() 구성합니다(전체 크기 이미지를 보려면 클릭).

UPDATE, INSERT 및 DELETE 탭의 드롭다운 목록을 (없음)으로 설정

그림 2: UPDATE, INSERT 및 DELETE 탭의 드롭다운 목록을 (없음)으로 설정합니다(전체 크기 이미지를 보려면 클릭).

DataList와 달리 Visual Studio는 데이터 원본에 바인딩한 ItemTemplate 후 반복기 컨트롤을 자동으로 만들지 않습니다. 또한 Repeater 컨트롤의 스마트 태그에 DataList에 있는 템플릿 편집 옵션이 없기 때문에 이를 ItemTemplate 선언적으로 추가해야 합니다. 제품 이름, 공급업체 및 범주를 표시한 이전 자습서와 동일하게 ItemTemplate 사용하겠습니다.

추가한 ItemTemplate후 Repeater 및 ObjectDataSource의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:Repeater ID="SortableProducts" DataSourceID="ProductsDataSource"
    EnableViewState="False" runat="server">
    <ItemTemplate>
        <h4><asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:Label></h4>
        Category:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'></asp:Label><br />
        Supplier:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'></asp:Label><br />
        <br />
        <br />
    </ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProducts">
</asp:ObjectDataSource>

그림 3에서는 브라우저를 통해 볼 때 이 페이지를 보여 줍니다.

각 제품의 이름, 공급업체 및 범주가 표시됩니다.

그림 3: 각 제품의 이름, 공급업체 및 범주가 표시됩니다(전체 크기 이미지를 보려면 클릭).

3단계: ObjectDataSource에 데이터 정렬 지시

Repeater에 표시되는 데이터를 정렬하려면 데이터를 정렬해야 하는 정렬 식의 ObjectDataSource에 알려야 합니다. ObjectDataSource가 해당 데이터를 검색하기 전에 먼저 이벤트를 실행 Selecting 하여 정렬 식을 지정할 수 있는 기회를 제공합니다. Selecting 이벤트 처리기는 형식이라는 속성 Arguments 이 있는 형식ObjectDataSourceSelectingEventArgsDataSourceSelectArguments의 개체에 전달됩니다. 이 DataSourceSelectArguments 클래스는 데이터 소비자의 데이터 관련 요청을 데이터 원본 제어로 전달하도록 설계되었으며 속성을 포함합니다SortExpression.

ASP.NET 페이지에서 ObjectDataSource로 정렬 정보를 전달하려면 이벤트에 대한 Selecting 이벤트 처리기를 만들고 다음 코드를 사용합니다.

Protected Sub ProductsDataSource_Selecting(ByVal sender As Object, _
    ByVal e As ObjectDataSourceSelectingEventArgs) _
    Handles ProductsDataSource.Selecting
    e.Arguments.SortExpression = sortExpression
End Sub

sortExpression 값은 데이터를 정렬할 데이터 필드의 이름(예: ProductName)에 할당되어야 합니다. 정렬 방향 관련 속성이 없으므로 데이터를 내림차순으로 정렬하려면 문자열 DESC 를 sortExpression 값(예: ProductName DESC)에 추가합니다.

계속해서 sortExpression에 대해 다른 하드 코딩된 값을 시도하고 브라우저에서 결과를 테스트합니다. 그림 4에서 보여 주듯이 ProductName DESC를 sortExpression으로 사용하는 경우 제품은 역순으로 이름을 기준으로 정렬됩니다.

제품은 역순으로 이름별로 정렬됩니다.

그림 4: 제품이 이름을 기준으로 사전순으로 정렬됩니다(전체 크기 이미지를 보려면 클릭).

4단계: 정렬 인터페이스 만들기 및 정렬 식 및 방향 기억

GridView에서 정렬 지원을 켜면 정렬 가능한 각 필드의 헤더 텍스트가 LinkButton으로 변환되고, 클릭할 때 그에 따라 데이터를 정렬합니다. 이러한 정렬 인터페이스는 데이터가 열에 깔끔하게 배치되는 GridView에 적합합니다. 그러나 DataList 및 Repeater 컨트롤의 경우 다른 정렬 인터페이스가 필요합니다. 데이터 표가 아닌 데이터 목록에 대한 일반적인 정렬 인터페이스는 데이터를 정렬할 수 있는 필드를 제공하는 드롭다운 목록입니다. 이 자습서에 대한 이러한 인터페이스를 구현해 보겠습니다.

반복기 위에 DropDownList 웹 컨트롤을 SortableProducts 추가하고 해당 ID 속성을 .로 SortBy설정합니다. 속성 창 속성의 줄임표를 Items 클릭하여 ListItem 컬렉션 편집기를 표시합니다. s를 추가하여 ListItem , 및 SupplierName 필드를 기준으로 ProductNameCategoryName데이터를 정렬합니다. 또한 이름을 기준으로 제품을 역순으로 정렬하는 A ListItem 를 추가합니다.

속성은 ListItem Text 모든 값(예: 이름)으로 설정할 수 있지만 속성은 Value 데이터 필드의 이름(예: ProductName)으로 설정해야 합니다. 결과를 내림차순으로 정렬하려면 ProductName DESC와 같은 데이터 필드 이름에 문자열 DESC를 추가합니다.

정렬 가능한 각 데이터 필드에 대한 ListItem 추가

그림 5: 정렬 가능한 데이터 필드 각각에 대한 추가 ListItem

마지막으로 DropDownList 오른쪽에 단추 웹 컨트롤을 추가합니다. 해당 및 RefreshRepeater 해당 ID Text 속성을 새로 고침으로 설정합니다.

s를 ListItem 만들고 새로 고침 단추를 추가한 후 DropDownList 및 단추의 선언적 구문은 다음과 유사하게 표시됩니다.

<asp:DropDownList ID="SortBy" runat="server">
    <asp:ListItem Value="ProductName">Name</asp:ListItem>
    <asp:ListItem Value="ProductName DESC">Name (Reverse Order)
        </asp:ListItem>
    <asp:ListItem Value="CategoryName">Category</asp:ListItem>
    <asp:ListItem Value="SupplierName">Supplier</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" ID="RefreshRepeater" Text="Refresh" />

정렬 DropDownList가 완료되면 하드 코딩된 SortBy``ListItem 정렬 식이 아닌 선택한 속성을 사용하도록 ObjectDataSource의 Selecting Value 이벤트 처리기를 업데이트해야 합니다.

Protected Sub ProductsDataSource_Selecting _
    (ByVal sender As Object, ByVal e As ObjectDataSourceSelectingEventArgs) _
    Handles ProductsDataSource.Selecting
    ' Have the ObjectDataSource sort the results by the
    ' selected sort expression
    e.Arguments.SortExpression = SortBy.SelectedValue
End Sub

이 시점에서 페이지를 처음 방문할 때 제품은 기본적으로 선택된 대로 데이터 필드를 SortBy ListItem 기준으로 ProductName 정렬됩니다(그림 6 참조). 범주와 같은 다른 정렬 옵션을 선택하고 새로 고침을 클릭하면 포스트백이 발생하고 그림 7과 같이 범주 이름으로 데이터를 다시 정렬합니다.

제품은 처음에 이름을 기준으로 정렬됩니다.

그림 6: 제품이 처음에 이름을 기준으로 정렬됨(전체 크기 이미지를 보려면 클릭)

이제 제품이 범주별로 정렬됩니다.

그림 7: 이제 제품이 범주별로 정렬됨(전체 크기 이미지를 보려면 클릭)

참고 항목

새로 고침 단추를 클릭하면 반복기 보기 상태가 비활성화되어 데이터가 자동으로 다시 정렬되므로 반복기가 모든 포스트백에서 해당 데이터 원본으로 다시 바인딩됩니다. 반복기 뷰 상태를 사용하도록 설정한 경우 정렬 드롭다운 목록을 변경해도 정렬 순서에 영향을 주지 않습니다. 이 문제를 해결하려면 Refresh Button 이벤트에 대한 이벤트 처리기를 만들고 Repeater 메서드 Click 를 호출 DataBind() 하여 반복기를 해당 데이터 원본에 다시 바인딩합니다.

정렬 식 및 방향 기억

정렬되지 않은 관련 포스트백이 발생할 수 있는 페이지에서 정렬 가능한 DataList 또는 Repeater를 만들 때는 포스트백에서 정렬 식과 방향을 기억해야 합니다. 예를 들어 이 자습서에서 각 제품에 삭제 단추를 포함하도록 Repeater를 업데이트한다고 상상해 보십시오. 사용자가 삭제 단추를 클릭하면 일부 코드를 실행하여 선택한 제품을 삭제한 다음 데이터를 Repeater에 다시 바인딩합니다. 정렬 세부 정보가 포스트백 간에 유지되지 않으면 화면에 표시되는 데이터가 원래 정렬 순서로 되돌아갑니다.

이 자습서의 경우 DropDownList는 정렬 식과 방향을 뷰 상태에 암시적으로 저장합니다. 다양한 정렬 옵션을 제공한 LinkButtons와 함께 다른 정렬 인터페이스를 사용하는 경우 포스트백에서 정렬 순서를 기억하기 위해 주의해야 합니다. 이는 정렬 매개 변수를 페이지 뷰 상태에 저장하거나, 쿼리 문자열에 정렬 매개 변수를 포함하거나, 다른 상태 지속성 기술을 통해 수행할 수 있습니다.

이 자습서의 이후 예제에서는 페이지 보기 상태에서 정렬 세부 정보를 유지하는 방법을 살펴봅니다.

5단계: 기본 페이징을 사용하는 DataList에 정렬 지원 추가

이전 자습서에서는 DataList를 사용하여 기본 페이징을 구현하는 방법을 검토했습니다. 페이징된 데이터를 정렬하는 기능을 포함하도록 이 이전 예제를 확장해 보겠습니다. 먼저 폴더의 SortingWithDefaultPaging.aspx 페이지와 Paging.aspx 페이지를 PagingSortingDataListRepeater 엽니다. Paging.aspx 페이지에서 원본 단추를 클릭하여 페이지의 선언적 태그를 봅니다. 선택한 텍스트를 복사하여(그림 8 참조) 태그 사이의 선언적 태그 SortingWithDefaultPaging.aspx<asp:Content> 붙여넣습니다.

asp:Content> 태그의 <선언적 태그를 Paging.aspx SortingWithDefaultPaging.aspx

그림 8: 태그 Paging.aspx SortingWithDefaultPaging.aspx 에서 <asp:Content> 선언적 태그 복제(전체 크기 이미지를 보려면 클릭)

선언적 태그를 복사한 후 페이지 코드 숨김 클래스의 메서드와 속성을 Paging.aspx 코드 숨김 클래스에 복사합니다 SortingWithDefaultPaging.aspx. 그런 다음 잠시 시간을 내어 브라우저에서 페이지를 봅니 SortingWithDefaultPaging.aspx 다. 와 동일한 기능 및 모양을 Paging.aspx표시해야 합니다.

기본 페이징 및 정렬 방법을 포함하도록 ProductsBLL 향상

이전 자습서에서는 개체를 반환하는 GetProductsAsPagedDataSource(pageIndex, pageSize) 클래스에서 ProductsBLL 메서드를 PagedDataSource 만들었습니다. 이 PagedDataSource 개체는 BLL GetProducts() 메서드를 통해 모든 제품으로 채워졌지만 DataList에 바인딩된 경우 지정된 pageIndexpageSize 입력 매개 변수에 해당하는 레코드만 표시되었습니다.

이 자습서의 앞부분에서는 ObjectDataSource의 Selecting 이벤트 처리기에서 정렬 식을 지정하여 정렬 지원을 추가했습니다. 이는 ObjectDataSource가 메서드에서 반환한 것과 같이 정렬할 수 있는 개체를 ProductsDataTable 반환 GetProducts() 할 때 잘 작동합니다. 그러나 메서드에서 PagedDataSource 반환된 개체는 GetProductsAsPagedDataSource 내부 데이터 원본의 정렬을 지원하지 않습니다. 대신 메서드를 배치하기 전에 메서드에서 반환된 GetProducts() 결과를 정렬해야 합니다PagedDataSource.

이 작업을 수행하려면 클래스GetProductsSortedAsPagedDataSource(sortExpression, pageIndex, pageSize)에서 새 메서드를 ProductsBLL 만듭니다. 메서드에서 반환 GetProducts()ProductsDataTable 값을 정렬하려면 기본값DataTableViewSort 속성을 지정합니다.

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductsSortedAsPagedDataSource _
    (sortExpression As String, pageIndex As Integer, pageSize As Integer) _
    As PagedDataSource
    ' Get ALL of the products
    Dim products As Northwind.ProductsDataTable = GetProducts()
    'Sort the products
    products.DefaultView.Sort = sortExpression
    ' Limit the results through a PagedDataSource
    Dim pagedData As New PagedDataSource()
    pagedData.DataSource = products.DefaultView
    pagedData.AllowPaging = True
    pagedData.CurrentPageIndex = pageIndex
    pagedData.PageSize = pageSize
    Return pagedData
End Function

이 메서드는 GetProductsSortedAsPagedDataSource 이전 자습서에서 만든 메서드와 GetProductsAsPagedDataSource 약간 다릅니다. 특히 GetProductsSortedAsPagedDataSource 추가 입력 매개 변수 sortExpression 를 수락하고 이 값을 Sort sDefaultView의 속성에 ProductDataTable 할당합니다. 몇 줄의 코드가 나중에 PagedDataSource 개체의 DataSource에 ProductDataTable DefaultView할당됩니다.

GetProductsSortedAsPagedDataSource 메서드 호출 및 SortExpression 입력 매개 변수 값 지정

메서드가 GetProductsSortedAsPagedDataSource 완료되면 다음 단계는 이 매개 변수의 값을 제공하는 것입니다. ObjectDataSource SortingWithDefaultPaging.aspx in은 현재 메서드를 호출 GetProductsAsPagedDataSource 하도록 구성되고 컬렉션에 지정된 두 입력 매개 변수를 통해 두 QueryStringParameters개의 입력 매개 변수를 SelectParameters 전달합니다. 이 두 QueryStringParameters 가지는 메서드의 pageIndexpageSize 매개 변수에 대한 GetProductsAsPagedDataSource 원본이 쿼리 문자열 필드 pageIndexpageSize.

GetProductsSortedAsPagedDataSource 메서드를 호출할 수 있도록 ObjectDataSource의 SelectMethod 속성을 업데이트합니다. 그런 다음, querystring 필드에서 sortExpressionsortExpression 입력 매개 변수에 액세스할 수 있도록 QueryStringParameter 매개 변수를 추가합니다. S를 QueryStringParameter DefaultValue ProductName으로 설정합니다.

이러한 변경 후 ObjectDataSource의 선언적 태그는 다음과 같이 표시됩니다.

<asp:ObjectDataSource ID="ProductsDefaultPagingDataSource"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProductsSortedAsPagedDataSource"
    OnSelected="ProductsDefaultPagingDataSource_Selected" runat="server">
    <SelectParameters>
        <asp:QueryStringParameter DefaultValue="ProductName"
            Name="sortExpression" QueryStringField="sortExpression"
            Type="String" />
        <asp:QueryStringParameter DefaultValue="0" Name="pageIndex"
            QueryStringField="pageIndex" Type="Int32" />
        <asp:QueryStringParameter DefaultValue="4" Name="pageSize"
            QueryStringField="pageSize" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

이 시점에서 SortingWithDefaultPaging.aspx 페이지는 제품 이름을 기준으로 결과를 사전순으로 정렬합니다(그림 9 참조). 이는 기본적으로 ProductName 값이 메서드의 sortExpression 매개 변수로 GetProductsSortedAsPagedDataSource 전달되기 때문입니다.

기본적으로 결과는 ProductName별로 정렬됩니다.

그림 9: 기본적으로 결과가 정렬됩니다 ProductName (전체 크기 이미지를 보려면 클릭).

쿼리 문자열 필드를 수동으로 추가 sortExpression 하면 결과와 같은 SortingWithDefaultPaging.aspx?sortExpression=CategoryName 결과가 지정된 sortExpression대로 정렬됩니다. 그러나 이 sortExpression 매개 변수는 다른 데이터 페이지로 이동할 때 쿼리 문자열에 포함되지 않습니다. 실제로 다음 또는 마지막 페이지 단추를 클릭하면 다시 Paging.aspx! 또한 현재 정렬 인터페이스가 없습니다. 사용자가 페이징된 데이터의 정렬 순서를 변경할 수 있는 유일한 방법은 쿼리 문자열을 직접 조작하는 것입니다.

정렬 인터페이스 만들기

먼저 사용자를 SortingWithDefaultPaging.aspx 보내고 쿼리 Paging.aspx문자열에 값을 포함 sortExpression 하도록 메서드를 업데이트 RedirectUser 해야 합니다. 또한 읽기 전용인 페이지 수준 명명된 SortExpression 속성을 추가해야 합니다. 이 속성은 이전 자습서에서 만든 속성과 PageSize 유사하게 PageIndex 쿼리 문자열 필드의 sortExpression 값(있는 경우)을 반환하고, 그렇지 않으면 기본값(ProductName)을 반환합니다.

현재 이 메서드는 RedirectUser 표시할 페이지의 인덱스에 대한 단일 입력 매개 변수만 허용합니다. 그러나 쿼리 문자열에 지정된 항목이 아닌 정렬 식을 사용하여 특정 데이터 페이지로 사용자를 리디렉션하려는 경우가 있을 수 있습니다. 잠시 후에 이 페이지에 대한 정렬 인터페이스를 만듭니다. 이 인터페이스에는 지정된 열을 기준으로 데이터를 정렬하기 위한 일련의 Button Web 컨트롤이 포함됩니다. 이러한 단추 중 하나를 클릭하면 적절한 정렬 식 값을 전달하는 사용자를 리디렉션하려고 합니다. 이 기능을 제공하려면 두 가지 버전의 메서드를 만듭니다 RedirectUser . 첫 번째 인덱스는 표시할 페이지 인덱스만 허용하고 두 번째 인덱스는 페이지 인덱스 및 정렬 식을 수락해야 합니다.

Private ReadOnly Property SortExpression() As String
    Get
        If Not String.IsNullOrEmpty(Request.QueryString("sortExpression")) Then
            Return Request.QueryString("sortExpression")
        Else
            Return "ProductName"
        End If
    End Get
End Property
Private Sub RedirectUser(ByVal sendUserToPageIndex As Integer)
    ' Use the SortExpression property to get the sort expression
    ' from the querystring
    RedirectUser(sendUserToPageIndex, SortExpression)
End Sub
Private Sub RedirectUser(ByVal sendUserToPageIndex As Integer,
    ByVal sendUserSortingBy As String)
    ' Send the user to the requested page with the
    ' requested sort expression
    Response.Redirect(String.Format("SortingWithDefaultPaging.aspx?" & _
        "pageIndex={0}&pageSize={1}&sortExpression={2}", _
        sendUserToPageIndex, PageSize, sendUserSortingBy))
End Sub

이 자습서의 첫 번째 예제에서는 DropDownList를 사용하여 정렬 인터페이스를 만들었습니다. 이 예제에서는 DataList 1 위에 배치된 세 개의 단추 웹 컨트롤을 사용하여 정렬 기준 ProductName, 하나는 for CategoryName및 1을 SupplierName기준으로 정렬합니다. 세 개의 단추 웹 컨트롤을 추가하고 해당 ID 컨트롤과 Text 속성을 적절하게 설정합니다.

<p>
    <asp:Button runat="server" id="SortByProductName"
        Text="Sort by Product Name" />
    <asp:Button runat="server" id="SortByCategoryName"
        Text="Sort by Category" />
    <asp:Button runat="server" id="SortBySupplierName"
        Text="Sort by Supplier" />
</p>

다음으로 각각에 Click 대한 이벤트 처리기를 만듭니다. 이벤트 처리기는 메서드를 RedirectUser 호출하여 적절한 정렬 식을 사용하여 사용자를 첫 번째 페이지로 반환해야 합니다.

Protected Sub SortByProductName_Click(sender As Object, e As EventArgs) _
    Handles SortByProductName.Click
    'Sort by ProductName
    RedirectUser(0, "ProductName")
End Sub
Protected Sub SortByCategoryName_Click(sender As Object, e As EventArgs) _
    Handles SortByCategoryName.Click
    'Sort by CategoryName
    RedirectUser(0, "CategoryName")
End Sub
Protected Sub SortBySupplierName_Click(sender As Object, e As EventArgs) _
    Handles SortBySupplierName.Click
    'Sort by SupplierName
    RedirectUser(0, "SupplierName")
End Sub

페이지를 처음 방문할 때 데이터는 제품 이름을 기준으로 사전순으로 정렬됩니다(그림 9 참조). 다음 단추를 클릭하여 데이터의 두 번째 페이지로 이동한 다음 범주별 정렬 단추를 클릭합니다. 그러면 범주 이름을 기준으로 정렬된 데이터의 첫 페이지로 돌아갑니다(그림 10 참조). 마찬가지로 공급업체별 정렬 단추를 클릭하면 데이터의 첫 번째 페이지에서 시작하여 공급자별로 데이터를 정렬합니다. 정렬 선택은 데이터가 페이징될 때 기억됩니다. 그림 11은 범주별로 정렬한 다음 데이터의 13번째 페이지로 이동한 후의 페이지를 보여줍니다.

범주별로 정렬된 제품

그림 10: 제품이 범주별로 정렬됨(전체 크기 이미지를 보려면 클릭)

정렬 식은 데이터를 페이징할 때 기억됩니다.

그림 11: 정렬 식은 데이터를 페이징할 때 기억됩니다(전체 크기 이미지를 보려면 클릭).

6단계: 반복기에서 레코드를 통한 사용자 지정 페이징

비효율적인 기본 페이징 기술을 사용하여 데이터를 통해 5단계 페이지에서 검사한 DataList 예제입니다. 충분히 많은 양의 데이터를 페이징하는 경우 사용자 지정 페이징을 사용해야 합니다. 대량의 데이터를 효율적으로 페이징하고 사용자 지정 페이징 데이터 정렬 자습서로 돌아가서 사용자 지정 페이징을 활용하고 사용자 지정 페이징 데이터를 정렬하기 위해 BLL에서 기본 페이징과 사용자 지정 페이징 및 만든 메서드의 차이점을 조사했습니다. 특히 이전 두 자습서에서는 다음 세 가지 메서드를 클래스에 ProductsBLL 추가했습니다.

  • GetProductsPaged(startRowIndex, maximumRows)는 startRowIndex에서 시작하여 maximumRows를 초과하지 않는 레코드의 특정 하위 집합을 반환합니다.
  • GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows) 는 지정된 sortExpression 입력 매개 변수를 기준으로 정렬된 레코드의 특정 하위 집합을 반환합니다.
  • TotalNumberOfProducts() 는 데이터베이스 테이블의 총 레코드 Products 수를 제공합니다.

이러한 메서드는 DataList 또는 Repeater 컨트롤을 사용하여 데이터를 효율적으로 페이저닝하고 정렬하는 데 사용할 수 있습니다. 이를 설명하기 위해 먼저 사용자 지정 페이징 지원을 사용하여 Repeater 컨트롤을 만들어 보겠습니다. 그런 다음 정렬 기능을 추가합니다.

폴더에서 SortingWithCustomPaging.aspx PagingSortingDataListRepeater 페이지를 열고 페이지에 반복기를 추가하여 해당 ID 속성을 Products.로 설정합니다. Repeater의 스마트 태그에서 새 ObjectDataSource를 만듭니다 ProductsDataSource. 클래스의 GetProductsPaged 메서드에서 ProductsBLL 해당 데이터를 선택하도록 구성합니다.

ProductsBLL 클래스의 GetProductsPaged 메서드를 사용하도록 ObjectDataSource 구성

그림 12: Class s GetProductsPaged 메서드를 사용하도록 ProductsBLL ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

UPDATE, INSERT 및 DELETE 탭의 드롭다운 목록을 (없음)으로 설정한 다음 다음 단추를 클릭합니다. 이제 데이터 원본 구성 마법사에서 메서드 startRowIndex 및 maximumRows 입력 매개 변수의 GetProductsPaged 원본을 묻는 메시지를 표시합니다. 실제로 이러한 입력 매개 변수는 무시됩니다. 대신 startRowIndex 및 maximumRows 값은 이 자습서의 첫 번째 데모에서 sortExpression을 지정한 방법과 마찬가지로 ObjectDataSource 이벤트 Selecting 처리기의 속성을 통해 Arguments 전달됩니다. 따라서 매개 변수 원본 드롭다운 목록을 None으로 설정된 마법사에 그대로 둡니다.

매개 변수 원본을 없음으로 설정된 상태로 둡니다.

그림 13: 매개 변수 원본을 없음으로 설정된 상태로 둡니다(전체 크기 이미지를 보려면 클릭).

참고 항목

ObjectDataSource의 EnablePaging 속성을 true.로 설정하지 마세요. 이로 인해 ObjectDataSource가 자체 startRowIndexmaximumRows 매개 변수를 SelectMethod 기존 매개 변수 목록에 자동으로 포함하게 됩니다. 이 속성은 EnablePaging 사용자 지정 페이징된 데이터를 GridView, DetailsView 또는 FormView 컨트롤에 바인딩할 때 유용합니다. 이러한 컨트롤에는 속성이 있을 때만 EnablePaging 사용할 수 있는 ObjectDataSource의 특정 동작이 예상되므로 true유용합니다. DataList 및 Repeater에 대한 페이징 지원을 수동으로 추가해야 하므로 ASP.NET 페이지 내에서 직접 필요한 기능을 준비하므로 이 속성을 (기본값으로) 그대로 false 둡니다.

마지막으로 제품 이름, 범주 및 공급자가 표시되도록 Repeater ItemTemplate 를 정의합니다. 이러한 변경 후 Repeater 및 ObjectDataSource의 선언적 구문은 다음과 유사하게 표시됩니다.

<asp:Repeater ID="Products" runat="server" DataSourceID="ProductsDataSource"
    EnableViewState="False">
    <ItemTemplate>
        <h4><asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:Label></h4>
        Category:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'></asp:Label><br />
        Supplier:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'></asp:Label><br />
        <br />
        <br />
    </ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsPaged" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="maximumRows" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

잠시 브라우저를 통해 페이지를 방문하여 레코드가 반환되지 않습니다. startRowIndexmaximumRows 매개 변수 값을 아직 지정하지 않았기 때문에 두 매개 변수 값 모두에 0 값이 전달되고 있기 때문입니다. 이러한 값을 지정하려면 ObjectDataSource 이벤트에 Selecting 대한 이벤트 처리기를 만들고 프로그래밍 방식으로 이러한 매개 변수 값을 각각 0과 5의 하드 코딩된 값으로 설정합니다.

Protected Sub ProductsDataSource_Selecting(sender As Object, _
    e As ObjectDataSourceSelectingEventArgs) _
    Handles ProductsDataSource.Selecting
    e.InputParameters("startRowIndex") = 0
    e.InputParameters("maximumRows") = 5
End Sub

이 변경으로 브라우저를 통해 볼 때 페이지에 처음 5개의 제품이 표시됩니다.

처음 다섯 개의 레코드가 표시됩니다.

그림 14: 처음 다섯 개의 레코드가 표시됩니다(전체 크기 이미지를 보려면 클릭).

참고 항목

그림 14에 나열된 제품은 효율적인 사용자 지정 페이징 쿼리를 수행하는 저장 프로시저가 결과를 ProductName기준으로 정렬하기 때문에 GetProductsPaged 제품 이름으로 정렬됩니다.

사용자가 페이지를 단계별로 실행할 수 있도록 하려면 시작 행 인덱스와 최대 행을 추적하고 포스트백에서 이러한 값을 기억해야 합니다. 기본 페이징 예제에서는 쿼리 문자열 필드를 사용하여 이러한 값을 유지했습니다. 이 데모의 경우 이 정보를 페이지 보기 상태로 유지해 보겠습니다. 다음 두 속성을 만듭니다.

Private Property StartRowIndex() As Integer
    Get
        Dim o As Object = ViewState("StartRowIndex")
        If o Is Nothing Then
            Return 0
        Else
            Return CType(o, Integer)
        End If
    End Get
    Set(ByVal value As Integer)
        ViewState("StartRowIndex") = value
    End Set
End Property
Private Property MaximumRows() As Integer
    Get
        Dim o As Object = ViewState("MaximumRows")
        If o Is Nothing Then
            Return 5
        Else
            Return CType(o, Integer)
        End If
    End Get
    Set(ByVal value As Integer)
        ViewState("MaximumRows") = value
    End Set
End Property

다음으로, 하드 코딩된 값 0과 5 대신 속성 및 MaximumRows 속성을 사용할 StartRowIndex 수 있도록 Selecting 이벤트 처리기의 코드를 업데이트합니다.

e.InputParameters("startRowIndex") = 0
e.InputParameters("maximumRows") = 5

이 시점에서 페이지에는 처음 5개의 레코드만 표시됩니다. 그러나 이러한 속성이 준비되면 페이징 인터페이스를 만들 준비가 된 것입니다.

페이징 인터페이스 추가

표시되는 데이터의 페이지와 총 페이지 수를 표시하는 레이블 웹 컨트롤을 포함하여 기본 페이징 예제에서 사용된 동일한 첫 번째, 이전, 다음, 마지막 페이징 인터페이스를 사용하겠습니다. 4개의 단추 웹 컨트롤과 레이블을 반복기 아래에 추가합니다.

<p>
    <asp:Button runat="server" ID="FirstPage" Text="<< First" />
    <asp:Button runat="server" ID="PrevPage" Text="< Prev" />
    <asp:Button runat="server" ID="NextPage" Text="Next >" />
    <asp:Button runat="server" ID="LastPage" Text="Last >>" />
</p>
<p>
    <asp:Label runat="server" ID="CurrentPageNumber"></asp:Label>
</p>

다음으로, 네 개의 단추에 대한 이벤트 처리기를 만듭니 Click 다. 이러한 단추 중 하나를 클릭하면 데이터를 업데이트 StartRowIndex 하고 리피터에 다시 바인딩해야 합니다. 첫 번째, 이전 및 다음 단추의 코드는 충분히 간단하지만 마지막 단추의 경우 데이터의 마지막 페이지에 대한 시작 행 인덱스를 어떻게 결정합니까? 이 인덱스를 계산하고 다음 및 마지막 단추를 사용할지 여부를 확인할 수 있도록 하려면 페이징되는 총 레코드 수를 알아야 합니다. 클래스의 TotalNumberOfProducts() 메서드를 ProductsBLL 호출하여 이를 확인할 수 있습니다. 메서드의 결과를 TotalNumberOfProducts() 반환하는 읽기 TotalRowCount 전용 페이지 수준 속성을 만들어 보겠습니다.

Private ReadOnly Property TotalRowCount() As Integer
    Get
        'Return the value from the TotalNumberOfProducts() method
        Dim productsAPI As New ProductsBLL()
        Return productsAPI.TotalNumberOfProducts()
    End Get
End Property

이 속성을 사용하면 이제 마지막 페이지의 시작 행 인덱스가 결정됩니다. 특히 1을 뺀 MaximumRows값의 TotalRowCount 정수 결과를 곱MaximumRows한 값입니다. 이제 네 개의 페이징 인터페이스 단추에 대한 이벤트 처리기를 작성 Click 할 수 있습니다.

Protected Sub FirstPage_Click(sender As Object, e As EventArgs) _
    Handles FirstPage.Click
    'Return to StartRowIndex of 0 and rebind data
    StartRowIndex = 0
    Products.DataBind()
End Sub
Protected Sub PrevPage_Click(sender As Object, e As EventArgs) _
    Handles PrevPage.Click
    'Subtract MaximumRows from StartRowIndex and rebind data
    StartRowIndex -= MaximumRows
    Products.DataBind()
End Sub
Protected Sub NextPage_Click(sender As Object, e As EventArgs) _
    Handles NextPage.Click
    'Add MaximumRows to StartRowIndex and rebind data
    StartRowIndex += MaximumRows
    Products.DataBind()
End Sub
Protected Sub LastPage_Click(sender As Object, e As EventArgs) _
    Handles LastPage.Click
    'Set StartRowIndex = to last page's starting row index and rebind data
    StartRowIndex = ((TotalRowCount - 1) \ MaximumRows) * MaximumRows
    Products.DataBind()
End Sub

마지막으로, 마지막 페이지를 볼 때 데이터의 첫 번째 페이지와 다음 및 마지막 단추를 볼 때 페이징 인터페이스에서 첫 번째 및 이전 단추를 사용하지 않도록 설정해야 합니다. 이렇게 하려면 ObjectDataSource의 Selecting 이벤트 처리기에 다음 코드를 추가합니다.

' Disable the paging interface buttons, if needed
FirstPage.Enabled = StartRowIndex <> 0
PrevPage.Enabled = StartRowIndex <> 0
Dim LastPageStartRowIndex As Integer = _
    ((TotalRowCount - 1) \ MaximumRows) * MaximumRows
NextPage.Enabled = (StartRowIndex < LastPageStartRowIndex)
LastPage.Enabled = (StartRowIndex < LastPageStartRowIndex)

현재 시작 행 인덱스에 따라 페이징 인터페이스 요소를 사용하거나 사용하지 않도록 설정하는 이러한 Click 이벤트 처리기 및 코드를 추가한 후 브라우저에서 페이지를 테스트합니다. 그림 15에서 알 수 있듯이 처음 페이지를 방문하면 첫 번째 단추와 이전 단추가 비활성화됩니다. [다음]을 클릭하면 데이터의 두 번째 페이지가 표시되고 마지막을 클릭하면 최종 페이지가 표시됩니다(그림 16 및 17 참조). 데이터의 마지막 페이지를 볼 때 다음 단추와 마지막 단추가 모두 비활성화됩니다.

제품의 첫 페이지를 볼 때 이전 단추와 마지막 단추가 비활성화됨

그림 15: 제품의 첫 페이지를 볼 때 이전 단추와 마지막 단추가 비활성화됨(전체 크기 이미지를 보려면 클릭)

제품의 두 번째 페이지가 표시됩니다.

그림 16: 제품의 두 번째 페이지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

마지막을 클릭하면 데이터의 마지막 페이지가 표시됩니다.

그림 17: 마지막을 클릭하면 데이터의 마지막 페이지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

7단계: 사용자 지정 페이징 반복기를 사용하여 정렬 지원 포함

이제 사용자 지정 페이징이 구현되었으므로 정렬 지원을 포함할 준비가 되었습니다. ProductsBLL 클래스의 GetProductsPagedAndSorted 메서드는 startRowIndex 및 maximumRows 입력 매개 변수와 동일GetProductsPaged하지만 추가 sortExpression 입력 매개 변수를 허용합니다. 이 메서드SortingWithCustomPaging.aspxGetProductsPagedAndSorted 사용하려면 다음 단계를 수행해야 합니다.

  1. ObjectDataSource의 SelectMethod 속성을 .로 GetProductsPaged GetProductsPagedAndSorted변경합니다.
  2. ObjectDataSource 컬렉션 SelectParameters 에 sortExpression Parameter 개체를 추가합니다.
  3. 페이지 보기 상태를 통해 포스트백 간에 해당 값을 유지하는 프라이빗 페이지 수준 SortExpression 속성을 만듭니다.
  4. ObjectDataSource의 Selecting sortExpression 매개 변수에 페이지 수준 SortExpression 속성의 값을 할당하도록 ObjectDataSource의 이벤트 처리기를 업데이트합니다.
  5. 정렬 인터페이스를 만듭니다.

ObjectDataSource의 SelectMethod 속성을 업데이트하고 sortExpressionParameter추가하여 시작합니다. sortExpression의 속성이 .로 설정되어 있는지 확인합니다String.Type Parameter 이러한 처음 두 작업을 완료한 후 ObjectDataSource의 선언적 태그는 다음과 같습니다.

<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProductsPagedAndSorted"
    OnSelecting="ProductsDataSource_Selecting">
    <SelectParameters>
        <asp:Parameter Name="sortExpression" Type="String" />
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="maximumRows" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

다음으로, 상태를 보기 위해 값이 serialize된 페이지 수준 SortExpression 속성이 필요합니다. 정렬 식 값이 설정되지 않은 경우 ProductName을 기본값으로 사용합니다.

Private Property SortExpression() As String
    Get
        Dim o As Object = ViewState("SortExpression")
        If o Is Nothing Then
            Return "ProductName"
        Else
            Return o.ToString()
        End If
    End Get
    Set(ByVal value As String)
        ViewState("SortExpression") = value
    End Set
End Property

ObjectDataSource가 메서드를 GetProductsPagedAndSorted 호출하기 전에 sortExpression Parameter 을 속성 값 SortExpression 으로 설정해야 합니다. Selecting 이벤트 처리기에서 다음 코드 줄을 추가합니다.

e.InputParameters("sortExpression") = SortExpression

남은 것은 정렬 인터페이스를 구현하는 것입니다. 마지막 예제에서와 같이 사용자가 제품 이름, 범주 또는 공급자별로 결과를 정렬할 수 있도록 하는 세 개의 Button Web 컨트롤을 사용하여 정렬 인터페이스를 구현해 보겠습니다.

<asp:Button runat="server" id="SortByProductName"
    Text="Sort by Product Name" />
<asp:Button runat="server" id="SortByCategoryName"
    Text="Sort by Category" />
<asp:Button runat="server" id="SortBySupplierName"
    Text="Sort by Supplier" />

이러한 세 개의 Button 컨트롤에 대한 이벤트 처리기를 만듭니 Click 다. 이벤트 처리기에서 0으로 다시 설정하고 StartRowIndex , 적절한 값으로 설정하고 SortExpression , 데이터를 Repeater에 다시 바인딩합니다.

Protected Sub SortByProductName_Click(sender As Object, e As EventArgs) _
    Handles SortByProductName.Click
    StartRowIndex = 0
    SortExpression = "ProductName"
    Products.DataBind()
End Sub
Protected Sub SortByCategoryName_Click(sender As Object, e As EventArgs) _
    Handles SortByCategoryName.Click
    StartRowIndex = 0
    SortExpression = "CategoryName"
    Products.DataBind()
End Sub
Protected Sub SortBySupplierName_Click(sender As Object, e As EventArgs) _
    Handles SortBySupplierName.Click
    StartRowIndex = 0
    SortExpression = "CompanyName"
    Products.DataBind()
End Sub

그게 전부입니다! 사용자 지정 페이징 및 정렬을 구현하는 여러 단계가 있었지만 단계는 기본 페이징에 필요한 단계와 매우 유사했습니다. 그림 18에서는 범주별로 정렬할 때 데이터의 마지막 페이지를 볼 때의 제품을 보여 줍니다.

범주별로 정렬된 데이터의 마지막 페이지가 표시됩니다.

그림 18: 범주별로 정렬된 마지막 데이터 페이지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

참고 항목

이전 예제에서는 공급자 SupplierName을 기준으로 정렬할 때 정렬 식으로 사용되었습니다. 그러나 사용자 지정 페이징 구현의 경우 CompanyName을 사용해야 합니다. 사용자 지정 페이징 GetProductsPagedAndSorted 구현을 담당하는 저장 프로시저가 정렬 식을 키워드로 ROW_NUMBER() 전달하기 때문입니다. 키워드에는 ROW_NUMBER() 별칭이 아닌 실제 열 이름이 필요합니다. 따라서 정렬 식에 쿼리()에 Suppliers 사용되는 SELECT 별칭 대신 테이블의 열 이름)SupplierName을 사용해야 CompanyName 합니다.

요약

DataList나 Repeater는 기본 제공 정렬 지원을 제공하지 않지만 약간의 코드와 사용자 지정 정렬 인터페이스를 사용하여 이러한 기능을 추가할 수 있습니다. 정렬을 구현할 때 페이징이 아닌 정렬 식을 ObjectDataSource 메서드 Select 에 전달된 개체를 통해 DataSourceSelectArguments 지정할 수 있습니다. 이 DataSourceSelectArguments 개체의 속성은 SortExpression ObjectDataSource의 Selecting 이벤트 처리기에서 할당할 수 있습니다.

이미 페이징 지원을 제공하는 DataList 또는 Repeater에 정렬 기능을 추가하려면 정렬 식을 허용하는 메서드를 포함하도록 비즈니스 논리 계층을 사용자 지정하는 것이 가장 쉬운 방법입니다. 그런 다음 ObjectDataSource의 SelectParameters매개 변수를 통해 이 정보를 전달할 수 있습니다.

이 자습서에서는 DataList 및 Repeater 컨트롤을 사용하여 페이징 및 정렬 검사를 완료합니다. 다음 및 마지막 자습서에서는 항목별로 사용자가 시작한 몇 가지 기능을 제공하기 위해 DataList 및 Repeater 템플릿에 단추 웹 컨트롤을 추가하는 방법을 살펴봅니다.

행복한 프로그래밍!

작성자 정보

7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 연구해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 자신 ASP.NET 24 시간에 2.0입니다. 그는 에서 mitchell@4GuysFromRolla.com찾을 http://ScottOnWriting.NET수있는 자신의 블로그를 통해 도달 할 수 있습니다 .

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 David Suru였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 선을 놓습니다 mitchell@4GuysFromRolla.com.