GridView에 단추를 추가하고 응답(C#)

작성자 : Scott Mitchell

PDF 다운로드

이 자습서에서는 템플릿과 GridView 또는 DetailsView 컨트롤의 필드에 사용자 지정 단추를 추가하는 방법을 살펴보겠습니다. 특히 사용자가 공급자를 통해 페이지를 처리할 수 있는 FormView가 있는 인터페이스를 빌드합니다.

소개

많은 보고 시나리오에는 보고서 데이터에 대한 읽기 전용 액세스가 포함되지만 보고서에 표시되는 데이터를 기반으로 작업을 수행하는 기능이 포함되는 것은 드문 일이 아닙니다. 일반적으로 여기에는 단추, LinkButton 또는 ImageButton 웹 컨트롤을 보고서에 표시되는 각 레코드와 함께 추가하여 클릭할 때 포스트백이 발생하고 일부 서버 쪽 코드를 호출하는 작업이 포함됩니다. 레코드별로 데이터를 편집하고 삭제하는 것이 가장 일반적인 예입니다. 실제로 데이터 삽입, 업데이트 및 삭제 개요 자습서부터 보았듯이 편집 및 삭제는 매우 일반적이므로 GridView, DetailsView 및 FormView 컨트롤은 코드 한 줄을 작성할 필요 없이 이러한 기능을 지원할 수 있습니다.

편집 및 삭제 단추 외에도 GridView, DetailsView 및 FormView 컨트롤에는 클릭 시 일부 사용자 지정 서버 쪽 논리를 수행하는 Buttons, LinkButtons 또는 ImageButtons도 포함될 수 있습니다. 이 자습서에서는 템플릿과 GridView 또는 DetailsView 컨트롤의 필드에 사용자 지정 단추를 추가하는 방법을 살펴보겠습니다. 특히 사용자가 공급자를 통해 페이지를 처리할 수 있는 FormView가 있는 인터페이스를 빌드합니다. 지정된 공급자의 경우 FormView는 단추 웹 컨트롤과 함께 공급업체에 대한 정보를 표시합니다. 이 컨트롤을 클릭하면 연결된 모든 제품이 중단됨으로 표시됩니다. 또한 GridView는 선택한 공급자가 제공한 제품을 나열하며, 각 행에는 클릭 시 제품의 UnitPrice 가격을 10% 인상하거나 줄이는 가격 인상 및 할인 가격 단추가 포함됩니다(그림 1 참조).

FormView 및 GridView 모두 사용자 지정 작업을 수행하는 단추 포함

그림 1: FormView 및 GridView 모두 사용자 지정 작업을 수행하는 단추가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

1단계: 단추 자습서 웹 페이지 추가

사용자 지정 단추를 추가하는 방법을 살펴보기 전에 먼저 이 자습서에 필요한 웹 사이트 프로젝트의 ASP.NET 페이지를 만들어 보겠습니다. 먼저 라는 CustomButtons새 폴더를 추가합니다. 다음으로, 해당 폴더에 다음 두 ASP.NET 페이지를 추가하여 각 페이지를 master 페이지와 Site.master 연결해야 합니다.

  • Default.aspx
  • CustomButtons.aspx

사용자 지정 Buttons-Related 자습서에 대한 ASP.NET 페이지 추가

그림 2: 사용자 지정 Buttons-Related 자습서에 대한 ASP.NET 페이지 추가

다른 폴더와 Default.aspx 마찬가지로 폴더의 CustomButtons 섹션에 자습서가 나열됩니다. 사용자 컨트롤은 SectionLevelTutorialListing.ascx 이 기능을 제공합니다. 따라서 솔루션 탐색기 페이지의 디자인 보기로 끌어 이 사용자 컨트롤 Default.aspx 을 에 추가합니다.

SectionLevelTutorialListing.ascx 사용자 컨트롤을 추가하여 Default.aspx

그림 3: 사용자 컨트롤을 SectionLevelTutorialListing.ascxDefault.aspx 추가합니다(전체 크기 이미지를 보려면 클릭).

마지막으로 페이지를 파일에 항목으로 추가합니다 Web.sitemap . 특히 페이징 및 정렬 다음에 다음 태그를 추가합니다.<siteMapNode>

<siteMapNode
    title="Adding Custom Buttons"
    description="Samples of Reports that Include Buttons for Performing
                  Server-Side Actions"
    url="~/CustomButtons/Default.aspx">
    <siteMapNode
        title="Using ButtonFields and Buttons in Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons as ButtonFields or within templates."
        url="~/CustomButtons/CustomButtons.aspx" />
</siteMapNode>

를 업데이트 Web.sitemap한 후 잠시 시간을 내어 브라우저를 통해 자습서 웹 사이트를 봅니다. 이제 왼쪽 메뉴에는 자습서 편집, 삽입 및 삭제를 위한 항목이 포함됩니다.

이제 사이트 맵에 사용자 지정 단추 자습서에 대한 항목이 포함됩니다.

그림 4: 이제 사이트 맵에 사용자 지정 단추 자습서에 대한 항목이 포함됩니다.

2단계: 공급자를 Lists FormView 추가

공급자를 나열하는 FormView를 추가하여 이 자습서를 시작하겠습니다. 소개에서 설명한 대로 이 FormView를 사용하면 사용자가 공급자를 통해 페이지를 탐색할 수 있으며 GridView에서 공급자가 제공한 제품을 표시합니다. 또한 이 FormView에는 클릭 시 모든 공급업체 제품을 중단된 것으로 표시하는 단추가 포함됩니다. FormView에 사용자 지정 단추를 추가하는 것을 고려하기 전에 먼저 공급업체 정보를 표시하도록 FormView를 만들어 보겠습니다.

먼저 폴더에서 CustomButtons.aspxCustomButtons 페이지를 엽니다. FormView를 도구 상자에서 Designer 끌어 페이지에 추가하고 해당 ID 속성을 로 Suppliers설정합니다. FormView의 스마트 태그에서 라는 SuppliersDataSource새 ObjectDataSource를 만들도록 선택합니다.

새 ObjectDataSource 명명된 SuppliersDataSource 만들기

그림 5: 새 ObjectDataSource 명명된 SuppliersDataSource 만들기(전체 크기 이미지를 보려면 클릭)

클래스의 GetSuppliers() 메서드에서 SuppliersBLL 쿼리할 수 있도록 이 새 ObjectDataSource를 구성합니다(그림 6 참조). 이 FormView는 공급자 정보를 업데이트하기 위한 인터페이스를 제공하지 않으므로 업데이트 탭의 드롭다운 목록에서 (없음) 옵션을 선택합니다.

SuppliersBLL 클래스의 GetSuppliers() 메서드를 사용하도록 데이터 원본 구성

그림 6: 클래스의 GetSuppliers() 메서드를 SuppliersBLL 사용하도록 데이터 원본 구성(전체 크기 이미지를 보려면 클릭)

ObjectDataSource를 구성한 후 Visual Studio는 FormView에 InsertItemTemplate대해 , EditItemTemplateItemTemplate 를 생성합니다. InsertItemTemplateEditItemTemplate 제거하고 공급자의 회사 이름 및 전화 번호만 표시되도록 을 수정 ItemTemplate 합니다. 마지막으로 스마트 태그에서 페이징 사용 확인란을 선택하거나 속성을 True로 설정 AllowPaging 하여 FormView에 대한 페이징 지원을 켭니다. 이러한 변경 내용이 변경되면 페이지의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False" AllowPaging="True">
    <ItemTemplate>
        <h3>
            <asp:Label ID="CompanyName" runat="server"
                Text='<%# Bind("CompanyName") %>' />
        </h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

그림 7은 브라우저를 통해 볼 때 CustomButtons.aspx 페이지를 보여줍니다.

FormView는 현재 선택한 공급자의 CompanyName 및 전화 필드를 Lists.

그림 7: FormView는 현재 선택한 공급업체의 CompanyNamePhone 필드를 Lists(전체 크기 이미지를 보려면 클릭)

3단계: 선택한 공급업체 제품을 Lists GridView 추가

FormView의 템플릿에 모든 제품 중단 단추를 추가하기 전에 먼저 선택한 공급자가 제공하는 제품을 나열하는 FormView 아래에 GridView를 추가해 보겠습니다. 이렇게 하려면 페이지에 GridView를 추가하고, 해당 ID 속성을 SuppliersProducts로 설정하고, 라는 SuppliersProductsDataSource새 ObjectDataSource를 추가합니다.

새 ObjectDataSource 명명된 SuppliersProductsDataSource 만들기

그림 8: 새 ObjectDataSource 명명된 SuppliersProductsDataSource 만들기(전체 크기 이미지를 보려면 클릭)

ProductsBLL 클래스의 GetProductsBySupplierID(supplierID) 메서드를 사용하도록 이 ObjectDataSource를 구성합니다(그림 9 참조). 이 GridView는 제품의 가격을 조정할 수 있지만 GridView에서 기본 제공 편집 또는 삭제 기능을 사용하지는 않습니다. 따라서 ObjectDataSource의 UPDATE, INSERT 및 DELETE 탭에 대한 드롭다운 목록을 (없음)으로 설정할 수 있습니다.

ProductsBLL 클래스의 GetProductsBySupplierID(supplierID) 메서드를 사용하도록 데이터 원본 구성

그림 9: 클래스의 GetProductsBySupplierID(supplierID) 메서드를 ProductsBLL 사용하도록 데이터 원본 구성(전체 크기 이미지를 보려면 클릭)

메서드는 GetProductsBySupplierID(supplierID) 입력 매개 변수를 허용하므로 ObjectDataSource 마법사에서 이 매개 변수 값의 원본을 묻는 메시지를 표시합니다. FormView의 SupplierID 값을 전달하려면 매개 변수 원본 드롭다운 목록을 Control으로 설정하고 ControlID 드롭다운 목록을 Suppliers (2단계에서 만든 FormView의 ID)로 설정합니다.

supplierID 매개 변수가 Suppliers FormView 컨트롤에서 와야 함을 나타냅니다.

그림 10: FormView 컨트롤에서 Suppliers 매개 변수가 와야 함을 나타냅니다supplierID(전체 크기 이미지를 보려면 클릭).

ObjectDataSource 마법사를 완료한 후 GridView에는 각 제품의 데이터 필드에 대한 BoundField 또는 CheckBoxField가 포함됩니다. CheckBoxField와 Discontinued 함께 및 UnitPrice BoundFields만 ProductName 표시하도록 이 항목을 자르겠습니다. 또한 텍스트의 서식이 통화로 지정되도록 BoundField의 서식 UnitPrice 을 지정해 보겠습니다. GridView 및 SuppliersProductsDataSource ObjectDataSource의 선언적 태그는 다음 태그와 유사합니다.

<asp:GridView ID="SuppliersProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="Suppliers" Name="supplierID"
            PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

이 시점에서 자습서는 master/세부 정보 보고서를 표시하여 사용자가 맨 위에 있는 FormView에서 공급자를 선택하고 하단의 GridView를 통해 해당 공급자가 제공하는 제품을 볼 수 있도록 합니다. 그림 11은 FormView에서 도쿄 트레이더 공급업체를 선택할 때 이 페이지의 스크린샷을 보여줍니다.

선택한 공급업체 제품이 GridView에 표시됩니다.

그림 11: 선택한 공급업체의 제품이 GridView에 표시됩니다(전체 크기 이미지를 보려면 클릭).

4단계: 공급자에 대한 모든 제품을 중단하는 DAL 및 BLL 메서드 만들기

FormView에 단추를 추가하려면 먼저 이 작업을 수행하는 DAL과 BLL 모두에 메서드를 추가해야 합니다. 특히 이 메서드의 이름은 DiscontinueAllProductsForSupplier(supplierID)입니다. FormView의 단추를 클릭하면 비즈니스 논리 계층에서 이 메서드를 호출하여 선택한 공급자의 SupplierID를 전달합니다. 그러면 BLL은 해당 데이터 액세스 계층 메서드를 호출하여 지정된 공급자의 제품을 중단하는 데이터베이스에 문을 실행 UPDATE 합니다.

이전 자습서에서 수행한 것처럼 DAL 메서드를 만든 다음 BLL 메서드를 만들고 마지막으로 ASP.NET 페이지에서 기능을 구현하는 상향식 방법을 사용합니다. 폴더에서 Northwind.xsd 형식화된 DataSet을 App_Code/DAL 열고 에 새 메서드를 ProductsTableAdapter 추가합니다(를 마우스 오른쪽 단추로 클릭하고 ProductsTableAdapter 쿼리 추가 선택). 이렇게 하면 TableAdapter 쿼리 구성 마법사가 표시되어 새 메서드를 추가하는 과정을 안내합니다. 먼저 DAL 메서드가 임시 SQL 문을 사용함을 나타냅니다.

임시 SQL 문을 사용하여 DAL 메서드 만들기

그림 12: 임시 SQL 문을 사용하여 DAL 메서드 만들기(전체 크기 이미지를 보려면 클릭)

다음으로 마법사는 만들 쿼리 유형에 대한 메시지를 표시합니다. 메서드는 DiscontinueAllProductsForSupplier(supplierID) 데이터베이스 테이블을 업데이트 Products 해야 하므로 지정된 supplierID에서 제공하는 모든 제품에 대해 필드를 1로 설정 Discontinued 하려면 데이터를 업데이트하는 쿼리를 만들어야 합니다.

UPDATE 쿼리 유형 선택

그림 13: 업데이트 쿼리 유형 선택(전체 크기 이미지를 보려면 클릭)

다음 마법사 화면에서는 DataTable에 정의된 Products 각 필드를 업데이트하는 TableAdapter의 기존 UPDATE 문을 제공합니다. 이 쿼리 텍스트를 다음 문으로 바꿉니다.

UPDATE [Products] SET
   Discontinued = 1
WHERE SupplierID = @SupplierID

이 쿼리를 입력하고 다음을 클릭하면 마지막 마법사 화면에서 새 메서드의 이름 사용을 DiscontinueAllProductsForSupplier묻습니다. 마침 단추를 클릭하여 마법사를 완료합니다. DataSet Designer 돌아오면 명명DiscontinueAllProductsForSupplier(@SupplierID)된 에 새 메서드가 ProductsTableAdapter 표시됩니다.

새 DAL 메서드의 이름을 DiscontinueAllProductsForSupplier로 지정합니다.

그림 14: 새 DAL 메서드 DiscontinueAllProductsForSupplier 이름 지정(전체 크기 이미지를 보려면 클릭)

DiscontinueAllProductsForSupplier(supplierID) 데이터 액세스 계층에서 만든 메서드를 사용하여 다음 작업은 비즈니스 논리 계층에서 메서드를 만드는 DiscontinueAllProductsForSupplier(supplierID) 것입니다. 이렇게 하려면 클래스 파일을 열고 ProductsBLL 다음을 추가합니다.

public int DiscontinueAllProductsForSupplier(int supplierID)
{
    return Adapter.DiscontinueAllProductsForSupplier(supplierID);
}

이 메서드는 단순히 제공된 supplierID 매개 변수 값을 따라 전달하여 DAL의 메서드를 호출 DiscontinueAllProductsForSupplier(supplierID) 합니다. 특정 상황에서 공급업체의 제품만 중단하도록 허용한 비즈니스 규칙이 있는 경우 BLL에서 이러한 규칙을 구현해야 합니다.

참고

클래스 DiscontinueAllProductsForSupplier(supplierID)UpdateProduct 오버로드와 ProductsBLL 달리 메서드 서명에는 특성(<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, Boolean)>)이 DataObjectMethodAttribute 포함되지 않습니다. 이렇게 하면 UPDATE 탭에 있는 ObjectDataSource의 데이터 원본 구성 마법사 드롭다운 목록에서 메서드가 제외 DiscontinueAllProductsForSupplier(supplierID) 됩니다. ASP.NET 페이지의 이벤트 처리기에서 직접 메서드를 DiscontinueAllProductsForSupplier(supplierID) 호출하기 때문에 이 특성을 생략했습니다.

5단계: FormView에 모든 제품 중단 단추 추가

BLL 및 DAL의 DiscontinueAllProductsForSupplier(supplierID) 메서드가 완료되면 선택한 공급자의 모든 제품을 중단하는 기능을 추가하는 마지막 단계는 FormView의 ItemTemplate에 단추 웹 컨트롤을 추가하는 것입니다. 단추 텍스트인 모든 제품 중단 및 ID 속성 값 DiscontinueAllProductsForSupplier이 인 공급자의 전화 번호 아래에 이러한 단추를 추가해 보겠습니다. FormView의 스마트 태그(그림 15 참조)에서 템플릿 편집 링크를 클릭하거나 선언적 구문을 통해 직접 Designer 통해 이 단추 웹 컨트롤을 추가할 수 있습니다.

FormView의 ItemTemplate에 모든 제품 중단 단추 웹 컨트롤 추가

그림 15: FormView ItemTemplate 에 모든 제품 중단 단추 웹 컨트롤 추가(전체 크기 이미지를 보려면 클릭)

페이지를 방문하는 사용자가 단추를 클릭하면 포스트백이 계속되고 FormView의 ItemCommand 이벤트가 발생합니다. 이 단추 클릭에 대한 응답으로 사용자 지정 코드를 실행하려면 이 이벤트에 대한 이벤트 처리기를 만들 수 있습니다. 그러나 FormView 내에서 Button, LinkButton 또는 ImageButton 웹 컨트롤을 클릭 때마다 이벤트가 발생한다는 ItemCommand 것을 이해합니다. 즉, ItemCommand 사용자가 FormView에서 한 페이지에서 다른 페이지로 이동하면 이벤트가 발생합니다. 사용자가 삽입, 업데이트 또는 삭제를 지원하는 FormView에서 새로 만들기, 편집 또는 삭제를 클릭할 때도 마찬가지입니다.

ItemCommand 어떤 단추를 클릭하든 관계없이 실행되므로 이벤트 처리기에서 모든 제품 중단 단추를 클릭했는지 또는 다른 단추인지 확인하는 방법이 필요합니다. 이를 위해 Button Web 컨트롤의 CommandName 속성을 식별 값으로 설정할 수 있습니다. 단추를 클릭하면 이 값이 CommandName 이벤트 처리기에 전달 ItemCommand 되므로 모든 제품 중단 단추가 단추를 클릭했는지 여부를 확인할 수 있습니다. 모든 제품 중단 단추의 CommandName 속성을 DiscontinueProducts 로 설정합니다.

마지막으로 클라이언트 쪽 확인 대화 상자를 사용하여 사용자가 선택한 공급업체의 제품을 실제로 중단하려고 함을 확인해 보겠습니다. 삭제할 때 Client-Side 확인 추가 자습서에서 보았듯이 약간의 JavaScript를 사용하여 이 작업을 수행할 수 있습니다. 특히 단추 웹 컨트롤의 OnClientClick 속성을 로 설정합니다. return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');

이러한 변경 후 FormView의 선언적 구문은 다음과 같이 표시됩니다.

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False"
    AllowPaging="True">
    <ItemTemplate>
        <h3><asp:Label ID="CompanyName" runat="server"
            Text='<%# Bind("CompanyName") %>'></asp:Label></h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
        <br />
        <asp:Button ID="DiscontinueAllProductsForSupplier" runat="server"
            CommandName="DiscontinueProducts" Text="Discontinue All Products"
            OnClientClick="return confirm('This will mark _all_ of this supplier\'s
                products as discontinued. Are you certain you want to do this?');" />
    </ItemTemplate>
</asp:FormView>

다음으로 FormView ItemCommand 의 이벤트에 대한 이벤트 처리기를 만듭니다. 이 이벤트 처리기에서 먼저 모든 제품 중단 단추를 클릭했는지 여부를 확인해야 합니다. 이 경우 클래스의 ProductsBLL instance 만들고 해당 메서드를 DiscontinueAllProductsForSupplier(supplierID) 호출하여 선택한 FormView의 를 SupplierID 전달하려고 합니다.

protected void Suppliers_ItemCommand(object sender, FormViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("DiscontinueProducts") == 0)
    {
        // The "Discontinue All Products" Button was clicked.
        // Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
        // First, get the SupplierID selected in the FormView
        int supplierID = (int)Suppliers.SelectedValue;
        // Next, create an instance of the ProductsBLL class
        ProductsBLL productInfo = new ProductsBLL();
        // Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
        productInfo.DiscontinueAllProductsForSupplier(supplierID);
    }
}

SupplierID FormView에서 현재 선택한 공급자의 은 FormView의 SelectedValue 속성을 사용하여 액세스할 수 있습니다. 속성은 SelectedValue FormView에 표시되는 레코드의 첫 번째 데이터 키 값을 반환합니다. 2단계에서 ObjectDataSource를 FormView에 다시 바인딩할 때 데이터 키 값이 끌어온 데이터 필드를 나타내는 FormView의 DataKeyNames 속성이 Visual Studio에서 자동으로 로 설정 SupplierID 되었습니다.

ItemCommand 이벤트 처리기를 만든 상태에서 잠시 시간을 내어 페이지를 테스트합니다. Cooperativa de Quesos 'Las Cabras' 공급업체로 이동합니다(FormView의 다섯 번째 공급업체임). 이 공급 업체는 두 가지 제품을 제공합니다, 케소 카브랄레스와 케소 만체고 라 파스토라, 둘 다 중단 되지 않습니다 .

Cooperativa de Quesos 'Las Cabras'가 사업을 중단하여 제품을 중단해야 한다고 상상해 보십시오. 모든 제품 중단 단추를 클릭합니다. 그러면 클라이언트 쪽 확인 대화 상자가 표시됩니다(그림 16 참조).

협동조합 데 케소스 라스 카브라스, 활성 제품 2개 공급

그림 16: Cooperativa de Quesos Las Cabras가 두 개의 활성 제품을 제공합니다(전체 크기 이미지를 보려면 클릭)

클라이언트 쪽 확인 대화 상자에서 확인을 클릭하면 양식 제출이 진행되어 FormView의 이벤트가 발생하는 포스트백이 ItemCommand 발생합니다. 그러면 만든 이벤트 처리기가 실행되어 메서드를 DiscontinueAllProductsForSupplier(supplierID) 호출하고 Queso Cabrales 및 Queso Manchego La Pastora 제품을 모두 중단합니다.

GridView의 뷰 상태를 사용하지 않도록 설정한 경우 GridView는 모든 포스트백의 기본 데이터 저장소로 다시 설정되므로 이 두 제품이 이제 중단되었음을 반영하도록 즉시 업데이트됩니다(그림 17 참조). 그러나 GridView에서 보기 상태를 사용하지 않도록 설정하지 않은 경우 이 변경 후 GridView에 데이터를 수동으로 다시 바인딩해야 합니다. 이 작업을 수행하려면 메서드를 호출한 직후 GridView의 DataBind() 메서드를 호출하기 DiscontinueAllProductsForSupplier(supplierID) 만 하면됩니다.

모든 제품 중단 단추를 클릭하면 공급업체 제품이 그에 따라 업데이트됩니다.

그림 17: 모든 제품 중단 단추를 클릭하면 공급업체 제품이 그에 따라 업데이트됩니다(전체 크기 이미지를 보려면 클릭).

6단계: 제품 가격 조정을 위한 비즈니스 논리 계층에서 UpdateProduct 오버로드 만들기

FormView의 모든 제품 중단 단추와 마찬가지로 GridView에서 제품의 가격을 높이고 줄이는 단추를 추가하려면 먼저 적절한 데이터 액세스 계층 및 비즈니스 논리 계층 메서드를 추가해야 합니다. DAL에 단일 제품 행을 업데이트하는 메서드가 이미 있으므로 BLL에서 메서드에 대한 UpdateProduct 새 오버로드를 만들어 이러한 기능을 제공할 수 있습니다.

과거 UpdateProduct 오버로드는 일부 제품 필드 조합을 스칼라 입력 값으로 가져온 다음 지정된 제품에 대한 필드만 업데이트했습니다. 이 오버로드의 경우 이 표준과 약간 다르며 대신 제품의 ProductID 및 를 조정할 UnitPrice 백분율을 전달합니다(새로운 조정된 UnitPrice 자체를 전달하는 것과 반대). 이 방법은 현재 제품의 UnitPrice를 결정하는 데 신경을 쓸 필요가 없으므로 ASP.NET 페이지 코드 숨김 클래스에서 작성해야 하는 코드를 간소화합니다.

이 자습서의 UpdateProduct 오버로드는 다음과 같습니다.

public bool UpdateProduct(decimal unitPriceAdjustmentPercentage, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    // Adjust the UnitPrice by the specified percentage (if it's not NULL)
    if (!product.IsUnitPriceNull())
        product.UnitPrice *= unitPriceAdjustmentPercentage;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

이 오버로드는 DAL의 GetProductByProductID(productID) 메서드를 통해 지정된 제품에 대한 정보를 검색합니다. 그런 다음 제품의 UnitPrice 데이터베이스 NULL 값이 할당되었는지 확인합니다. 이 경우 가격은 비정형 상태로 남아 있습니다. 그러나 값NULLUnitPrice이 아닌 경우 메서드는 지정된 백분율(unitPriceAdjustmentPercent)로 제품의 UnitPrice 를 업데이트합니다.

7단계: GridView에 증가 및 감소 단추 추가

GridView(및 DetailsView)는 모두 필드 컬렉션으로 구성됩니다. BoundFields, CheckBoxFields 및 TemplateFields 외에도 ASP.NET 이름에서 알 수 있듯이 각 행에 대해 Button, LinkButton 또는 ImageButton이 있는 열로 렌더링되는 ButtonField를 포함합니다. FormView와 마찬가지로 GridView 페이 징 단추, 편집 또는 삭제 단추, 정렬 단추 등의 단추를 클릭하면 포스트백이 발생하고 GridView의 RowCommand 이벤트가 발생합니다.

ButtonField에는 CommandName 각 Buttons 속성에 지정된 값을 할당하는 속성이 있습니다 CommandName . FormView CommandName 와 마찬가지로 이 값은 이벤트 처리기에서 RowCommand 클릭한 단추를 결정하는 데 사용됩니다.

두 개의 새 ButtonFields를 GridView에 추가해 보겠습니다. 하나는 단추 텍스트가 가격 +10%이고 다른 하나는 가격 -10%입니다. 이러한 ButtonFields를 추가하려면 GridView의 스마트 태그에서 열 편집 링크를 클릭하고 왼쪽 위에 있는 목록에서 ButtonField 필드 유형을 선택하고 추가 단추를 클릭합니다.

GridView에 두 개의 ButtonFields 추가

그림 18: GridView에 단추 필드 2개 추가

처음 두 GridView 필드로 표시되도록 두 ButtonFields를 이동합니다. 다음으로, 이 두 ButtonFields의 속성을 각각 Price +10% 및 Price -10%로 CommandName 설정하고 속성을 IncreasePrice 및 DecreasePrice로 설정합니다Text. 기본적으로 ButtonField는 단추 열을 LinkButtons로 렌더링합니다. 그러나 ButtonField의 ButtonType 속성을 통해 변경할 수 있습니다. 이 두 개의 ButtonFields를 일반 푸시 단추로 렌더링해 보겠습니다. 따라서 속성을 ButtonButtonType 설정합니다. 그림 19는 이러한 변경 내용이 적용된 후의 필드 대화 상자를 보여줍니다. GridView의 선언적 태그입니다.

ButtonFields 텍스트, CommandName 및 ButtonType 속성 구성

그림 19: ButtonFields Text, CommandNameButtonType 속성 구성

<asp:GridView ID="SuppliersProducts" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:ButtonField ButtonType="Button" CommandName="IncreasePrice"
            Text="Price +10%" />
        <asp:ButtonField ButtonType="Button" CommandName="DecreasePrice"
            Text="Price -10%" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

이러한 ButtonFields를 만들면 마지막 단계는 GridView 이벤트에 RowCommand 대한 이벤트 처리기를 만드는 것입니다. 가격 +10% 또는 가격 -10% 단추를 클릭했기 때문에 발생한 경우 이 이벤트 처리기는 단추를 클릭한 행의 를 확인한 ProductID 다음 클래스의 UpdateProduct 메서드를 호출 ProductsBLL 하여 와 ProductID함께 적절한 UnitPrice 백분율 조정을 전달해야 합니다. 다음 코드는 다음 작업을 수행합니다.

protected void SuppliersProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("IncreasePrice") == 0 ||
        e.CommandName.CompareTo("DecreasePrice") == 0)
    {
        // The Increase Price or Decrease Price Button has been clicked
        // Determine the ID of the product whose price was adjusted
        int productID =
            (int)SuppliersProducts.DataKeys[Convert.ToInt32(e.CommandArgument)].Value;
        // Determine how much to adjust the price
        decimal percentageAdjust;
        if (e.CommandName.CompareTo("IncreasePrice") == 0)
            percentageAdjust = 1.1M;
        else
            percentageAdjust = 0.9M;

        // Adjust the price
        ProductsBLL productInfo = new ProductsBLL();
        productInfo.UpdateProduct(percentageAdjust, productID);
    }
}

가격 +10% 또는 가격 -10% 단추를 클릭한 행의 를 확인 ProductID 하려면 GridView의 DataKeys 컬렉션을 참조해야 합니다. 이 컬렉션은 각 GridView 행에 대해 속성에 DataKeyNames 지정된 필드의 값을 보유합니다. ObjectDataSource를 GridView DataKeys(rowIndex).Value 에 바인딩할 때 GridView의 DataKeyNames 속성이 Visual Studio의 ProductID로 설정되었으므로 지정된 rowIndex에 대한 를 제공합니다ProductID.

ButtonField는 매개 변수를 통해 단추를 클릭한 행의 rowIndexe.CommandArgument 자동으로 전달합니다. 따라서 가격 +10% 또는 가격 -10% 단추를 클릭한 행의 를 확인 ProductID 하려면 를 사용합니다 Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value).

모든 제품 중단 단추와 마찬가지로 GridView의 보기 상태를 사용하지 않도록 설정한 경우 GridView는 모든 포스트백의 기본 데이터 저장소로 다시 설정되므로 단추 중 하나를 클릭하여 발생하는 가격 변경을 반영하도록 즉시 업데이트됩니다. 그러나 GridView에서 보기 상태를 사용하지 않도록 설정하지 않은 경우 이 변경 후 GridView에 데이터를 수동으로 다시 바인딩해야 합니다. 이 작업을 수행하려면 메서드를 호출한 직후 GridView의 DataBind() 메서드를 호출하기 UpdateProduct 만 하면됩니다.

그림 20은 켈리 할머니의 홈스테드에서 제공하는 제품을 볼 때의 페이지를 보여줍니다. 그림 21은 할머니의 보이센베리 스프레드에 대해 가격 +10% 버튼을 두 번 클릭한 후의 결과와 노스우드 크랜베리 소스의 경우 가격 -10% 버튼을 한 번 클릭한 결과를 보여줍니다.

GridView에는 가격 +10% 및 가격 -10% 단추가 포함되어 있습니다.

그림 20: GridView에는 가격 +10% 및 가격 -10% 단추가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

첫 번째 및 세 번째 제품의 가격은 가격 +10% 및 가격 -10% 단추를 통해 업데이트되었습니다.

그림 21: 첫 번째 및 세 번째 제품의 가격이 가격 +10% 및 가격 -10% 단추를 통해 업데이트되었습니다(전체 크기 이미지를 보려면 클릭).

참고

GridView(및 DetailsView)에는 Buttons, LinkButtons 또는 ImageButtons가 TemplateFields에 추가되어 있을 수도 있습니다. BoundField와 마찬가지로 이러한 단추를 클릭하면 포스트백이 유도되어 GridView의 RowCommand 이벤트가 발생합니다. 그러나 TemplateField에 단추를 추가할 때 Button의 CommandArgument 는 ButtonFields를 사용할 때처럼 행의 인덱스로 자동으로 설정되지 않습니다. 이벤트 처리기 내에서 RowCommand 클릭한 단추의 행 인덱스를 결정해야 하는 경우 다음과 같은 코드를 사용하여 TemplateField 내의 선언적 구문에서 Button의 CommandArgument 속성을 수동으로 설정해야 합니다.
<asp:Button runat="server" ... CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'.

요약

GridView, DetailsView 및 FormView 컨트롤에는 모두 Buttons, LinkButtons 또는 ImageButtons가 포함될 수 있습니다. 이러한 단추를 클릭하면 포스트백이 발생하고 FormView 및 ItemCommand DetailsView 컨트롤과 GridView의 RowCommand 이벤트에서 이벤트가 발생합니다. 이러한 데이터 웹 컨트롤에는 레코드 삭제 또는 편집과 같은 일반적인 명령 관련 작업을 처리하는 기본 제공 기능이 있습니다. 그러나 클릭할 때 사용자 지정 코드를 실행하여 응답하는 단추를 사용할 수도 있습니다.

이렇게 하려면 또는 RowCommand 이벤트에 대한 ItemCommand 이벤트 처리기를 만들어야 합니다. 이 이벤트 처리기에서 먼저 들어오는 CommandName 값을 검사 클릭한 단추를 확인한 다음 적절한 사용자 지정 작업을 수행합니다. 이 자습서에서는 단추 및 ButtonFields를 사용하여 지정된 공급업체에 대한 모든 제품을 중단하거나 특정 제품의 가격을 10% 높이거나 줄이는 방법을 알아보았습니다.

행복한 프로그래밍!

저자 정보

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