DropDownList 두 개로 마스터/세부 정보 필터링(C#)

작성자 : Scott Mitchell

PDF 다운로드

이 자습서에서는 두 개의 DropDownList 컨트롤을 사용하여 원하는 부모 및 조부모 레코드를 선택하여 세 번째 계층을 추가하도록 master/세부 관계를 확장합니다.

소개

이전 자습서에서는 범주로 채워진 단일 DropDownList 및 선택한 범주에 속하는 제품을 보여 주는 GridView를 사용하여 간단한 master/세부 정보 보고서를 표시하는 방법을 검토했습니다. 이 보고서 패턴은 일대다 관계가 있고 여러 일 대 다 관계를 포함하는 시나리오에서 작동하도록 쉽게 확장할 수 있는 레코드를 표시할 때 잘 작동합니다. 예를 들어 주문 입력 시스템에는 고객, 주문 및 주문 품목에 해당하는 테이블이 있습니다. 지정된 고객은 각 주문이 여러 항목으로 구성된 여러 주문을 가질 수 있습니다. 이러한 데이터는 두 개의 DropDownLists와 GridView를 사용하여 사용자에게 표시될 수 있습니다. 첫 번째 DropDownList에는 데이터베이스의 각 고객에 대한 목록 항목이 있으며, 두 번째 고객의 콘텐츠는 선택한 고객이 주문한 주문입니다. GridView는 선택한 순서의 품목을 나열합니다.

Northwind 데이터베이스에는 , OrdersOrder Details 테이블에 정식 고객/주문/주문 세부 정보 정보가 Customers포함되어 있지만 이러한 테이블은 아키텍처에서 캡처되지 않습니다. 그럼에도 불구하고 여전히 두 개의 종속 DropDownList를 사용하는 것을 설명할 수 있습니다. 첫 번째 DropDownList는 범주를 나열하고 두 번째는 선택한 범주에 속하는 제품을 나열합니다. 그런 다음 DetailsView는 선택한 제품의 세부 정보를 나열합니다.

1단계: 범주 만들기 및 채우기 드롭다운 목록

첫 번째 목표는 범주를 나열하는 DropDownList를 추가하는 것입니다. 이러한 단계는 이전 자습서에서 자세히 검토되었지만 완성도를 위해 여기에 요약되어 있습니다.

폴더에서 MasterDetailsDetails.aspxFiltering 페이지를 열고 페이지에 DropDownList를 추가하고 해당 ID 속성을 Categories로 설정한 다음 스마트 태그에서 데이터 원본 구성 링크를 클릭합니다. 데이터 원본 구성 마법사에서 새 데이터 원본을 추가하도록 선택합니다.

DropDownList에 대한 새 데이터 원본 추가

그림 1: DropDownList에 대한 새 데이터 원본 추가(전체 크기 이미지를 보려면 클릭)

새 데이터 원본은 당연히 ObjectDataSource여야 합니다. 이 새 ObjectDataSource CategoriesDataSource 의 이름을 지정하고 개체의 GetCategories() 메서드를 CategoriesBLL 호출하게 합니다.

CategoriesBLL 클래스를 사용하도록 선택

그림 2: 클래스를 사용하도록 CategoriesBLL 선택(전체 크기 이미지를 보려면 클릭)

GetCategories() 메서드를 사용하도록 ObjectDataSource 구성

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

ObjectDataSource를 구성한 후에도 DropDownList에 Categories 표시할 데이터 원본 필드와 목록 항목의 값으로 구성해야 하는 데이터 원본 필드를 지정해야 합니다. CategoryName 필드를 표시로 설정하고 CategoryID 각 목록 항목의 값으로 설정합니다.

DropDownList에서 CategoryName 필드를 표시하고 CategoryID를 값으로 사용하도록 설정

그림 4: DropDownList에 필드를 표시 CategoryName 하고 값으로 사용 CategoryID (전체 크기 이미지를 보려면 클릭)

이 시점에서 테이블의 레코드로 채워진 DropDownList 컨트롤(Categories)이 있습니다 Categories . 사용자가 DropDownList에서 새 범주를 선택하면 2단계에서 만들려는 제품 DropDownList를 새로 고치기 위해 포스트백이 수행됩니다. 따라서 DropDownList의 스마트 태그에서 categories AutoPostBack 사용 옵션을 검사.

범주 드롭다운 목록에 AutoPostBack 사용

그림 5: DropDownList에 Categories AutoPostBack 사용(전체 크기 이미지를 보려면 클릭)

2단계: 두 번째 드롭다운 목록에 선택한 범주의 제품 표시

DropDownList가 Categories 완료되면 다음 단계는 선택한 범주에 속하는 제품의 DropDownList를 표시하는 것입니다. 이렇게 하려면 이라는 ProductsByCategory페이지에 다른 DropDownList를 추가합니다. DropDownList와 Categories 마찬가지로 이라는 ProductsByCategoryDataSourceDropDownList에 대한 새 ObjectDataSource를 ProductsByCategory 만듭니다.

ProductsByCategory DropDownList에 대한 새 데이터 원본 추가

그림 6: DropDownList에 대한 ProductsByCategory 새 데이터 원본 추가(전체 크기 이미지를 보려면 클릭)

ProductsByCategoryDataSource라는 새 ObjectDataSource 만들기

그림 7: 새 ObjectDataSource 이름 ProductsByCategoryDataSource 만들기(전체 크기 이미지를 보려면 클릭)

ProductsByCategory DropDownList는 선택한 범주에 속하는 제품만 표시해야 하므로 ObjectDataSource가 개체에서 메서드를 GetProductsByCategoryID(categoryID)ProductsBLL 호출하도록 합니다.

ProductsBLL이 선택되고 다음 단추가 강조 표시된 데이터 원본 구성 - productsByCategoryDataSource 창의 스크린샷

그림 8: 클래스 사용 ProductsBLL 선택(전체 크기 이미지를 보려면 클릭)

GetProductsByCategoryID(categoryID) 메서드를 사용하도록 ObjectDataSource 구성

그림 9: 메서드를 사용하도록 GetProductsByCategoryID(categoryID) ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

마법사의 마지막 단계에서는 매개 변수의 categoryID 값을 지정해야 합니다. DropDownList에서 선택한 항목에 이 매개 변수를 Categories 할당합니다.

Category DropDownList에서 categoryID 매개 변수 값을 가져옵니다.

그림 10: DropDownList에서 Categories 매개 변수 값 끌어오기categoryID(전체 크기 이미지를 보려면 클릭)

ObjectDataSource를 구성하면 DropDownList 항목의 표시 및 값에 사용되는 데이터 원본 필드를 지정하기만 하면 됩니다. ProductName 필드를 표시하고 필드를 값으로 사용합니다ProductID.

DropDownList의 ListItems 텍스트 및 값 속성에 사용되는 데이터 원본 필드 지정

그림 11: DropDownList의 ListItemTextValue 속성에 사용되는 데이터 원본 필드 지정(전체 크기 이미지를 보려면 클릭)

ObjectDataSource 및 ProductsByCategory DropDownList가 구성된 경우 페이지에 두 개의 DropDownList가 표시됩니다. 첫 번째 항목은 모든 범주를 나열하고 두 번째 항목은 선택한 범주에 속하는 제품을 나열합니다. 사용자가 첫 번째 DropDownList에서 새 범주를 선택하면 포스트백이 계속되고 두 번째 DropDownList가 반등하여 새로 선택한 범주에 속하는 제품을 표시합니다. 그림 12 및 13은 브라우저를 통해 볼 때 실제로 표시됩니다 MasterDetailsDetails.aspx .

페이지를 처음 방문하면 음료 범주가 선택됩니다.

그림 12: 페이지를 처음 방문할 때 음료 범주가 선택됩니다(전체 크기 이미지를 보려면 클릭).

다른 범주를 선택하면 새 범주의 제품이 표시됩니다.

그림 13: 다른 범주를 선택하면 새 범주의 제품이 표시됩니다(전체 크기 이미지를 보려면 클릭).

현재 DropDownList가 productsByCategory 변경되면 포스트백이 발생하지 않습니다 . 그러나 DetailsView를 추가하여 선택한 제품의 세부 정보를 표시하면 포스트백이 수행됩니다(3단계). 따라서 DropDownList의 스마트 태그에서 AutoPostBack 사용 확인란을 productsByCategory 검사.

제품에 대해 AutoPostBack 기능을 사용하도록 설정ByCategory DropDownList

그림 14: DropDownList에 자동 productsByCategory 포스트백 기능 사용(전체 크기 이미지를 보려면 클릭)

3단계: DetailsView를 사용하여 선택한 제품에 대한 세부 정보 표시

마지막 단계는 DetailsView에서 선택한 제품의 세부 정보를 표시하는 것입니다. 이렇게 하려면 페이지에 DetailsView를 추가하고 해당 ID 속성을 ProductDetails로 설정하고 새 ObjectDataSource를 만듭니다. 매개 변수 값에 대해 DropDownList의 선택한 값을 ProductsByCategory 사용하여 클래스의 GetProductByProductID(productID) 메서드에서 ProductsBLL 해당 데이터를 가져오도록 이 ObjectDataSource를 productID 구성합니다.

ProductsBLL이 선택되고 다음 단추가 강조 표시된 데이터 원본 구성 - productsByCategoryDataSource 창의 스크린샷

그림 15: 클래스 사용 ProductsBLL 선택(전체 크기 이미지를 보려면 클릭)

GetProductByProductID(productID) 메서드를 사용하도록 ObjectDataSource 구성

그림 16: 메서드를 사용하도록 GetProductByProductID(productID) ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

ProductsByCategory DropDownList에서 productID 매개 변수 값을 가져옵니다.

그림 17: DropDownList에서 ProductsByCategory 매개 변수 값 끌어오 productID 기(전체 크기 이미지를 보려면 클릭)

DetailsView에서 사용 가능한 필드를 표시하도록 선택할 수 있습니다. , SupplierIDCategoryID 필드를 제거하고 ProductID나머지 필드의 순서를 다시 지정하고 서식을 지정했습니다. 또한 DetailsView 및 HeightWidth 속성을 지워서 DetailsView를 지정된 크기로 제한하지 않고 데이터를 가장 잘 표시하는 데 필요한 너비로 확장할 수 있도록 했습니다. 전체 태그는 다음과 같습니다.

<asp:DetailsView ID="ProductDetails" runat="server"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="Product" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName"
          HeaderText="Category" ReadOnly="True"
          SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
          HeaderText="Supplier" ReadOnly="True"
          SortExpression="SupplierName" />
        <asp:BoundField DataField="QuantityPerUnit"
          HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice"
          DataFormatString="{0:c}" HeaderText="Price"
          HtmlEncode="False" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
          HeaderText="UnitsInStock" SortExpression="Units In Stock" />
        <asp:BoundField DataField="UnitsOnOrder"
          HeaderText="UnitsOnOrder" SortExpression="Units On Order" />
        <asp:BoundField DataField="ReorderLevel"
          HeaderText="ReorderLevel" SortExpression="Reorder Level" />
        <asp:CheckBoxField DataField="Discontinued"
          HeaderText="Discontinued" SortExpression="Discontinued" />
    </Fields>
</asp:DetailsView>

잠시 시간을 내어 MasterDetailsDetails.aspx 브라우저에서 페이지를 사용해 보세요. 언뜻 보기에 모든 것이 원하는 대로 작동하는 것처럼 보일 수 있지만 미묘한 문제가 있습니다. 새 범주를 선택하면 DropDownList가 선택한 범주 ProductsByCategory 에 대한 해당 제품을 포함하도록 업데이트되지만 ProductDetails DetailsView는 이전 제품 정보를 계속 표시했습니다. DetailsView는 선택한 범주에 대해 다른 제품을 선택할 때 업데이트됩니다. 또한 충분히 철저하게 테스트하는 경우 DropDownList에서 Categories 음료를 선택한 다음, Condiments, Confections 등 새 범주를 지속적으로 선택하면 다른 모든 범주를 선택하면 DetailsView가 새로 고쳐집니다 ProductDetails .

이 문제를 연결하는 데 도움이 되도록 특정 예제를 살펴보겠습니다. 페이지를 처음 방문하면 음료 범주가 선택되고 관련 제품이 DropDownList에 ProductsByCategory 로드됩니다. Chai는 선택한 제품이며 세부 정보는 그림 18과 ProductDetails 같이 DetailsView에 표시됩니다.

선택한 제품의 세부 정보가 DetailsView에 표시됩니다.

그림 18: 선택한 제품의 세부 정보가 DetailsView에 표시됩니다(전체 크기 이미지를 보려면 클릭).

범주 선택을 음료에서 Condiments로 변경하면 포스트백이 ProductsByCategory 발생하고 DropDownList가 그에 따라 업데이트되지만 DetailsView는 여전히 Chai에 대한 세부 정보를 표시합니다.

이전에 선택한 제품의 세부 정보가 계속 표시됩니다.

그림 19: 이전에 선택한 제품의 세부 정보가 계속 표시됩니다(전체 크기 이미지를 보려면 클릭).

목록에서 새 제품을 선택하면 DetailsView가 예상대로 새로 고쳐집니다. 제품을 변경한 후 새 범주를 선택하면 DetailsView가 다시 새로 고쳐지지 않습니다. 그러나 새 제품을 선택하는 대신 새 범주를 선택한 경우 DetailsView가 새로 고쳐집니다. 세상에서 무슨 일이 일어나고 있는가?

문제는 페이지의 수명 주기에서 타이밍 문제입니다. 페이지가 요청되면 렌더링으로 여러 단계를 진행합니다. 이러한 단계 중 하나에서 ObjectDataSource는 검사 제어하여 해당 값이 SelectParameters 변경되었는지 확인합니다. 이 경우 ObjectDataSource에 바인딩된 데이터 웹 컨트롤은 디스플레이를 새로 고쳐야 한다는 것을 알고 있습니다. 예를 들어 새 범주를 선택하면 ProductsByCategoryDataSource ObjectDataSource는 해당 매개 변수 값이 변경되었음을 감지하고 ProductsByCategory DropDownList가 자체적으로 다시 바인딩되어 선택한 범주에 대한 제품을 가져옵니다.

이 상황에서 발생하는 문제는 ObjectDataSources가 변경된 매개 변수에 대해 검사 페이지 수명 주기의 지점이 연결된 데이터 웹 컨트롤을 다시 바인딩하기 전에 발생한다는 것입니다. 따라서 새 범주 ProductsByCategoryDataSource 를 선택할 때 ObjectDataSource는 매개 변수 값의 변경 내용을 검색합니다. 그러나 DetailsView에서 ProductDetails 사용하는 ObjectDataSource는 DropDownList가 아직 반등하지 않았기 때문에 ProductsByCategory 이러한 변경 내용을 기록하지 않습니다. 수명 주기 ProductsByCategory 의 뒷부분에서 DropDownList는 ObjectDataSource에 다시 바인딩되어 새로 선택한 범주에 대한 제품을 가져옵니다. ProductsByCategory DropDownList의 값이 변경된 ProductDetails 동안 DetailsView의 ObjectDataSource는 매개 변수 값 검사 이미 수행했으므로 DetailsView는 이전 결과를 표시합니다. 이 상호 작용은 그림 20에 설명되어 있습니다.

ProductDetails DetailsView의 ObjectDataSource에서 변경 내용을 확인한 후 ProductsByCategory DropDownList 값이 변경됨

그림 20: ProductsByCategory DetailsView의 ObjectDataSource에서 변경 내용을 확인한 후 ProductDetails DropDownList 값이 변경됨(전체 크기 이미지를 보려면 클릭)

이 문제를 해결하려면 DropDownList가 바인딩된 ProductDetails 후 DetailsView를 ProductsByCategory 명시적으로 다시 바인딩해야 합니다. DropDownList DataBound 의 이벤트가 발생할 때 DetailsView의 DataBind() 메서드를 ProductsByCategory 호출 ProductDetails 하여 이 작업을 수행할 수 있습니다. 다음 이벤트 처리기 코드를 페이지의 코드 숨김 클래스에 MasterDetailsDetails.aspx 추가합니다(이벤트 처리기를 추가하는 방법에 대한 설명은 "프로그래밍 방식으로 ObjectDataSource의 매개 변수 값 설정"을 참조하세요.)

protected void ProductsByCategory_DataBound(object sender, EventArgs e)
{
    ProductDetails.DataBind();
}

DetailsView의 DataBind() 메서드에 대한 ProductDetails 이 명시적 호출이 추가된 후 자습서는 예상대로 작동합니다. 그림 21은 이러한 변화가 이전 문제를 어떻게 해결했는지 강조 표시합니다.

ProductsByCategory DropDownList의 DataBound 이벤트가 발생하면 ProductDetails DetailsView가 명시적으로 새로 고쳐집니다.

그림 21: ProductDetails DropDownList의 DataBound 이벤트가 발생할 때 ProductsByCategory DetailsView가 명시적으로 새로 고쳐집니다(전체 크기 이미지를 보려면 클릭).

요약

DropDownList는 master 및 세부 정보 레코드 간에 일대다 관계가 있는 master/세부 정보 보고서에 이상적인 사용자 인터페이스 요소 역할을 합니다. 이전 자습서에서는 단일 DropDownList를 사용하여 선택한 범주에 표시되는 제품을 필터링하는 방법을 알아보았습니다. 이 자습서에서는 제품의 GridView를 DropDownList로 바꾸고 DetailsView를 사용하여 선택한 제품의 세부 정보를 표시했습니다. 이 자습서에서 설명하는 개념은 고객, 주문 및 주문 항목과 같은 여러 일대다 관계를 포함하는 데이터 모델로 쉽게 확장할 수 있습니다. 일반적으로 일대다 관계의 각 "일" 엔터티에 대해 항상 DropDownList를 추가할 수 있습니다.

행복한 프로그래밍!

저자 정보

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

특별 감사

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