라디오 단추의 GridView 열 추가(C#)

작성자 : Scott Mitchell

PDF 다운로드

이 자습서에서는 GridView 컨트롤에 라디오 단추 열을 추가하여 사용자에게 GridView의 단일 행을 선택하는 보다 직관적인 방법을 제공하는 방법을 살펴봅니다.

소개

GridView 컨트롤은 다양한 기본 제공 기능을 제공합니다. 여기에는 텍스트, 이미지, 하이퍼링크 및 단추를 표시하기 위한 다양한 필드가 포함되어 있습니다. 추가 사용자 지정을 위한 템플릿을 지원합니다. 마우스를 몇 번 클릭하면 단추를 통해 각 행을 선택할 수 있는 GridView를 만들거나 편집 또는 삭제 기능을 사용할 수 있습니다. 제공된 기능의 과다에도 불구하고 지원되지 않는 추가 기능을 추가해야 하는 경우가 많습니다. 이 자습서와 다음 두 자습서에서는 추가 기능을 포함하도록 GridView 기능을 향상시키는 방법을 살펴봅니다.

이 자습서와 다음 자습서에서는 행 선택 프로세스를 향상시키는 데 중점을 두고 있습니다. 세부 정보 세부 정보 보기와 함께 선택 가능한 마스터 GridView를 사용하여 마스터/세부 정보에서 검사한 대로 선택 단추가 포함된 GridView에 CommandField를 추가할 수 있습니다. 클릭하면 포스트백이 계속되고 GridView의 SelectedIndex 속성이 선택 단추를 클릭한 행의 인덱스로 업데이트됩니다. 세부 정보 세부 정보 보기와 함께 선택 가능한 Master GridView를 사용하는 마스터/세부 정보 자습서에서는 이 기능을 사용하여 선택한 GridView 행에 대한 세부 정보를 표시하는 방법을 알아보았습니다.

선택 단추는 여러 상황에서 작동하지만 다른 경우에는 작동하지 않을 수 있습니다. 단추를 사용하는 대신 라디오 단추와 확인란이라는 두 가지 다른 사용자 인터페이스 요소가 선택 영역에 일반적으로 사용됩니다. 선택 단추 대신 각 행에 라디오 단추 또는 확인란이 포함되도록 GridView를 보강할 수 있습니다. 사용자가 GridView 레코드 중 하나만 선택할 수 있는 시나리오에서는 선택 단추보다 라디오 단추가 선호될 수 있습니다. 사용자가 웹 기반 전자 메일 애플리케이션과 같은 여러 레코드를 선택할 수 있는 경우 사용자가 여러 메시지를 선택하여 확인란을 삭제하려는 경우 선택 단추 또는 라디오 단추 사용자 인터페이스에서 사용할 수 없는 기능을 제공합니다.

이 자습서에서는 GridView에 라디오 단추 열을 추가하는 방법을 살펴봅니다. 진행 자습서에서는 확인란을 사용하여 탐색합니다.

1단계: GridView 웹 페이지 향상 만들기

라디오 단추 열을 포함하도록 GridView를 향상시키기 전에 먼저 이 자습서와 다음 두 가지에 필요한 웹 사이트 프로젝트에 ASP.NET 페이지를 만들어 보겠습니다. 먼저 라는 EnhancedGridView새 폴더를 추가합니다. 다음으로, 해당 폴더에 다음 ASP.NET 페이지를 추가하여 각 페이지를 master 페이지와 Site.master 연결해야 합니다.

  • Default.aspx
  • RadioButtonField.aspx
  • CheckBoxField.aspx
  • InsertThroughFooter.aspx

SqlDataSource-Related 자습서에 대한 ASP.NET 페이지 추가

그림 1: SqlDataSource-Related 자습서에 대한 ASP.NET 페이지 추가

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

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

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

마지막으로 이 네 페이지를 파일에 항목으로 추가합니다 Web.sitemap . 특히 SqlDataSource 컨트롤 <siteMapNode>사용 다음에 다음 태그를 추가합니다.

<siteMapNode 
    title="Enhancing the GridView" 
    url="~/EnhancedGridView/Default.aspx" 
    description="Augment the user experience of the GridView control.">
    <siteMapNode 
        url="~/EnhancedGridView/RadioButtonField.aspx" 
        title="Selection via a Radio Button Column" 
        description="Explore how to add a column of radio buttons in the GridView." />
    <siteMapNode 
        url="~/EnhancedGridView/CheckBoxField.aspx" 
        title="Selection via a Checkbox Column" 
        description="Select multiple records in the GridView by using a column of 
            checkboxes." />
    <siteMapNode 
        url="~/EnhancedGridView/InsertThroughFooter.aspx" 
        title="Add New Records through the Footer" 
        description="Learn how to allow users to add new records through the 
            GridView's footer." />
</siteMapNode>

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

이제 사이트 맵에 GridView 자습서 향상을 위한 항목이 포함됩니다.

그림 3: 이제 사이트 맵에 GridView 향상 자습서에 대한 항목이 포함됩니다.

2단계: GridView에 공급업체 표시

이 자습서에서는 각 GridView 행에 라디오 단추를 제공하는 미국의 공급업체를 나열하는 GridView를 빌드해 보겠습니다. 라디오 단추를 통해 공급자를 선택한 후 사용자는 단추를 클릭하여 공급업체 제품을 볼 수 있습니다. 이 작업은 사소한 것처럼 들릴 수 있지만 특히 까다로울 수 있는 미묘한 차이가 많이 있습니다. 이러한 미묘한 차이를 살펴보기 전에 먼저 공급업체를 나열하는 GridView를 살펴보겠습니다.

먼저 도구 상자에서 EnhancedGridView Designer GridView를 끌어 폴더의 페이지를 엽니다RadioButtonField.aspx. GridView를 IDSuppliers 설정하고 스마트 태그에서 새 데이터 원본을 만들도록 선택합니다. 특히 개체에서 해당 데이터를 끌어오는 ObjectDataSource라는 개체 SuppliersDataSourceSuppliersBLL 만듭니다.

새 ObjectDataSource 명명된 SuppliersDataSource 만들기

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

비즈니스 개체 SuppliersBLL이 선택되고 다음 단추가 강조 표시된 데이터 원본 구성 - SuppliersDataSource 창의 스크린샷

그림 5: 클래스를 사용하도록 SuppliersBLL ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

미국에 있는 공급업체만 나열하려고 하므로 SELECT 탭의 GetSuppliersByCountry(country) 드롭다운 목록에서 메서드를 선택합니다.

SELECT 탭이 열려 있는 데이터 원본 구성 - SuppliersDataSource 창의 스크린샷. GetSupplierByCountry 메서드 옵션이 선택되고 다음 단추가 강조 표시됩니다.

그림 6: 클래스를 사용하도록 SuppliersBLL ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

업데이트 탭에서 (없음) 옵션을 선택하고 다음을 클릭합니다.

UPDATE 탭이 열려 있는 데이터 원본 구성 - SuppliersDataSource 창의 스크린샷 메서드 옵션(없음)이 선택되고 다음 단추가 강조 표시됩니다.

그림 7: 클래스를 사용하도록 SuppliersBLL ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

메서드는 GetSuppliersByCountry(country) 매개 변수를 수락하므로 데이터 원본 구성 마법사에서 해당 매개 변수의 원본을 묻는 메시지를 표시합니다. 하드 코딩된 값(이 예제에서는 미국)을 지정하려면 매개 변수 원본 드롭다운 목록을 없음으로 설정하고 텍스트 상자에 기본값을 입력합니다. 마침을 클릭하여 마법사를 완료합니다.

국가 매개 변수의 기본값으로 USA 사용

그림 8: 매개 변수의 기본값 country 으로 USA 사용(전체 크기 이미지를 보려면 클릭)

마법사를 완료한 후 GridView에는 각 공급자 데이터 필드에 대한 BoundField가 포함됩니다. , City및 BoundFields를 CompanyName제외한 모든 를 제거하고 BoundFields HeaderText 속성의 CompanyName 이름을 Supplier로 바꿉 Country 니다. 이렇게 하면 GridView 및 ObjectDataSource 선언적 구문이 다음과 유사하게 표시됩니다.

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="CompanyName" HeaderText="Supplier" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL">
    <SelectParameters>
        <asp:Parameter DefaultValue="USA" Name="country" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

이 자습서에서는 사용자가 공급자 목록과 동일한 페이지 또는 다른 페이지에서 선택한 공급업체 제품을 볼 수 있도록 허용해 보겠습니다. 이를 수용하려면 두 개의 단추 웹 컨트롤을 페이지에 추가합니다. 이 두 단추의 s를 및 로 ListProducts 설정 ID 했는데, 이 경우 포스트백을 클릭하면 선택한 공급업체 제품이 동일한 페이지에 나열되지만, SendToProducts 를 클릭하면 사용자가 제품을 나열하는 다른 페이지로 휘SendToProducts저어집니다.ListProducts

그림 9는 브라우저를 Suppliers 통해 볼 때 GridView 및 두 개의 단추 웹 컨트롤을 보여 줍니다.

미국의 공급업체의 이름, 도시 및 국가 정보가 나열되어 있습니다.

그림 9: 미국의 공급업체의 이름, 도시 및 국가 정보가 나열되어 있습니다(전체 크기 이미지를 보려면 클릭).

3단계: 라디오 단추 열 추가

이 시점에서 Suppliers GridView에는 미국에 있는 각 공급업체의 회사 이름, 도시 및 국가를 표시하는 세 개의 BoundFields가 있습니다. 그러나 여전히 라디오 단추 열이 부족합니다. 아쉽게도 GridView에는 기본 제공 RadioButtonField가 포함되어 있지 않습니다. 그렇지 않으면 그리드에 추가하고 수행할 수 있습니다. 대신 TemplateField를 추가하고 라디오 단추를 렌더링하도록 구성 ItemTemplate 하여 각 GridView 행에 대한 라디오 단추를 만들 수 있습니다.

처음에는 TemplateField의 에 RadioButton 웹 컨트롤을 추가하여 원하는 사용자 인터페이스를 구현할 수 있다고 가정할 ItemTemplate 수 있습니다. 실제로 GridView의 각 행에 단일 라디오 단추가 추가되지만 라디오 단추를 그룹화할 수 없으므로 상호 배타적이지 않습니다. 즉, 최종 사용자는 GridView에서 여러 라디오 단추를 동시에 선택할 수 있습니다.

RadioButton 웹 컨트롤의 TemplateField를 사용하는 것이 필요한 기능을 제공하지는 않지만 결과 라디오 단추가 그룹화되지 않은 이유를 살펴보는 것이 좋습니다. 먼저 Suppliers GridView에 TemplateField를 추가하여 맨 왼쪽 필드로 만듭니다. 그런 다음 GridView의 스마트 태그에서 템플릿 편집 링크를 클릭하고 도구 상자에서 TemplateField s ItemTemplate 로 RadioButton 웹 컨트롤을 끌어옵니다(그림 10 참조). RadioButton의 ID 속성을 로 RowSelector 설정하고 GroupName 속성을 로 SuppliersGroup설정합니다.

ItemTemplate에 RadioButton 웹 컨트롤 추가

그림 10: 에 RadioButton 웹 컨트롤 ItemTemplate 추가(전체 크기 이미지를 보려면 클릭)

Designer 통해 이러한 추가를 수행한 후 GridView의 태그는 다음과 유사하게 표시됩니다.

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:RadioButton ID="RowSelector" runat="server" 
                    GroupName="SuppliersGroup" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CompanyName" HeaderText="Supplier" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
    </Columns>
</asp:GridView>

RadioButton의 GroupName 속성 은 일련의 라디오 단추를 그룹화하는 데 사용됩니다. 동일한 GroupName 값을 가진 모든 RadioButton 컨트롤은 그룹화된 것으로 간주됩니다. 한 번에 하나의 라디오 단추만 그룹에서 선택할 수 있습니다. 속성 렌더링 GroupName 된 라디오 단추의 name 특성에 대 한 값을 지정합니다. 브라우저는 라디오 단추 name 특성을 검사하여 라디오 단추 그룹화가 결정됩니다.

에 RadioButton 웹 컨트롤이 ItemTemplate추가되면 브라우저를 통해 이 페이지를 방문하여 표 행의 라디오 단추를 클릭합니다. 그림 11과 같이 라디오 단추가 그룹화되지 않아 모든 행을 선택할 수 있습니다.

GridView의 라디오 단추가 그룹화되지 않음

그림 11: GridView의 라디오 단추가 그룹화되지 않음(전체 크기 이미지를 보려면 클릭)

라디오 단추가 그룹화되지 않는 이유는 동일한 GroupName 속성 설정에도 불구하고 렌더링된 name 특성이 다르기 때문입니다. 이러한 차이점을 확인하려면 브라우저에서 보기/원본을 수행하고 라디오 단추 태그를 검사합니다.

<input id="ctl00_MainContent_Suppliers_ctl02_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl02$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl03_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl03$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl04_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl04$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl05_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl05$SuppliersGroup" 
    type="radio" value="RowSelector" />

id 특성이 모두 name 속성 창 지정된 정확한 값이 아니라 여러 다른 ID 값 앞에 추가되는 방법을 확인합니다. 렌더링된 및 name 특성의 전면에 추가된 id 추가 ID 값은 ID 부모가 제어 IDGridViewRow 하는 라디오 단추의 s, GridView의 ID, 콘텐츠 컨트롤의 ID및 웹 양식의 입니다ID. 이러한 ID 항목은 GridView에서 렌더링된 각 웹 컨트롤에 고유 id 하고 name 값이 있도록 추가됩니다.

렌더링된 각 컨트롤에는 다른 nameid 컨트롤이 필요하며, 이는 브라우저가 클라이언트 쪽의 각 컨트롤을 고유하게 식별하는 방식과 포스트백 시 발생한 작업 또는 변경 내용을 웹 서버에 식별하는 방법이기 때문입니다. 예를 들어 RadioButton의 확인 상태가 변경 될 때마다 일부 서버 쪽 코드를 실행하려고한다고 상상해보겠습니다. RadioButton의 AutoPostBack 속성을 true 로 설정하고 이벤트에 대한 CheckChanged 이벤트 처리기를 만들어 이 작업을 수행할 수 있습니다. 그러나 모든 라디오 단추에 대해 렌더링된 name 값과 id 값이 동일한 경우 포스트백 시 클릭한 특정 RadioButton을 확인할 수 없습니다.

간단히 말해서 RadioButton 웹 컨트롤을 사용하여 GridView에서 라디오 단추 열을 만들 수 없다는 것입니다. 대신, 적절한 태그가 각 GridView 행에 삽입되도록 하기 위해 다소 고풍스러운 기술을 사용해야 합니다.

참고

RadioButton 웹 컨트롤과 마찬가지로 템플릿에 추가할 때 라디오 단추 HTML 컨트롤에는 고유 name 특성이 포함되므로 그리드의 라디오 단추가 그룹화되지 않습니다. HTML 컨트롤에 익숙하지 않은 경우 특히 ASP.NET 2.0에서 HTML 컨트롤이 거의 사용되지 않으므로 이 메모를 무시해도 됩니다. 그러나 자세히 알아보려면 K. Scott Allen 의 블로그 항목 웹 컨트롤 및 HTML 컨트롤을 참조하세요.

리터럴 컨트롤을 사용하여 라디오 단추 태그 삽입

GridView 내의 모든 라디오 단추를 올바르게 그룹화하려면 라디오 단추 태그 ItemTemplate를 에 수동으로 삽입해야 합니다. 각 라디오 단추에는 동일한 name 특성이 필요하지만 고유한 id 특성이 있어야 합니다(클라이언트 쪽 스크립트를 통해 라디오 단추에 액세스하려는 경우). 사용자가 라디오 단추를 선택하고 페이지를 다시 게시하면 브라우저는 선택한 라디오 단추의 value 특성 값을 다시 보냅니다. 따라서 각 라디오 단추에는 고유한 value 특성이 필요합니다. 마지막으로, 포스트백 시 선택한 하나의 라디오 단추에 특성을 추가 checked 해야 합니다. 그렇지 않으면 사용자가 선택하고 다시 게시한 후 라디오 단추가 기본 상태로 돌아갑니다(모두 선택되지 않음).

템플릿에 하위 수준 태그를 삽입하기 위해 수행할 수 있는 두 가지 방법이 있습니다. 하나는 코드 숨김 클래스에 정의된 형식 지정 메서드에 대한 태그와 호출을 혼합하여 수행하는 것입니다. 이 기술은 GridView 컨트롤 자습서의 TemplateFields 사용 자습서에서 처음 설명했습니다. 이 경우 다음과 같이 표시될 수 있습니다.

<input type="radio" id='<%# GetUniqueRadioButtonID(...) %>' 
    name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... />

GetUniqueRadioButton 여기서 및 GetRadioButtonValue 는 각 라디오 단추에 대한 적절한 idvalue 특성 값을 반환하는 코드 숨김 클래스에 정의된 메서드입니다. 이 방법은 및 value 특성을 할당하는 데 id 적합하지만 데이터 바인딩 구문은 데이터가 GridView에 처음 바인딩된 경우에만 실행되므로 특성 값을 지정 checked 해야 할 때는 부족합니다. 따라서 GridView에 뷰 상태가 사용하도록 설정된 경우 서식 지정 메서드는 페이지가 처음 로드되거나 GridView가 데이터 원본에 명시적으로 리바운드될 때만 실행되므로 특성을 설정하는 checked 함수는 포스트백에서 호출되지 않습니다. 그것은 다소 미묘한 문제와이 문서의 scope 넘어 조금, 그래서 나는이에 그것을 떠날 것이다. 그러나 위의 접근 방식을 사용하여 중단되는 지점까지 작업하는 것이 좋습니다. 이러한 연습은 작업 버전에 더 가까워지지는 않지만 GridView 및 데이터 바인딩 수명 주기에 대한 심층적인 이해를 촉진하는 데 도움이 됩니다.

템플릿에 사용자 지정 하위 수준 태그를 삽입하는 다른 방법 및 이 자습서에 사용할 방법은 템플릿에 리터럴 컨트롤 을 추가하는 것입니다. 그런 다음 GridView RowCreated 또는 RowDataBound 이벤트 처리기에서 리터럴 컨트롤에 프로그래밍 방식으로 액세스하고 해당 Text 속성을 태그로 설정하여 내보낼 수 있습니다.

먼저 TemplateField ItemTemplate의 에서 RadioButton을 제거하여 리터럴 컨트롤로 대체합니다. 리터럴 컨트롤 s를 IDRadioButtonMarkup설정합니다.

ItemTemplate에 리터럴 컨트롤 추가

그림 12: 에 리터럴 컨트롤 ItemTemplate 추가(전체 크기 이미지를 보려면 클릭)

다음으로 GridView RowCreated 이벤트에 대한 이벤트 처리기를 만듭니다. 데이터가 RowCreated GridView에 다시 반환되는지 여부에 관계없이 추가된 모든 행에 대해 이벤트가 한 번 발생합니다. 즉, RowCreated 데이터가 뷰 상태에서 다시 로드될 때 포스트백에서도 이벤트가 계속 발생하며, 이는 데이터가 데이터 웹 컨트롤에 명시적으로 바인딩된 경우에만 발생하는 대신 RowDataBound 사용하는 이유입니다.

이 이벤트 처리기에서는 데이터 행을 처리하는 경우에만 진행하려고 합니다. 각 데이터 행에 대해 프로그래밍 방식으로 리터럴 컨트롤을 RadioButtonMarkup 참조하고 해당 Text 속성을 내보내는 태그로 설정합니다. 다음 코드에서 알 수 있듯이 내보낸 태그는 특성이 name 로 설정된 SuppliersGroup라디오 단추를 만듭니다. 해당 id 특성은 로 설정 RowSelectorX되고, 여기서 X 는 GridView 행의 인덱스이며 value 해당 특성은 GridView 행의 인덱스로 설정됩니다.

protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Grab a reference to the Literal control
        Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
        // Output the markup except for the "checked" attribute
        output.Text = string.Format(
            @"<input type="radio" name="SuppliersGroup" " +
            @"id="RowSelector{0}" value="{0}" />", e.Row.RowIndex);
    }
}

GridView 행이 선택되고 포스트백이 발생하면 선택한 공급자의 에 관심이 SupplierID 있습니다. 따라서 각 라디오 단추의 값은 GridView 행의 인덱스가 아닌 실제 SupplierID 값이어야 한다고 생각할 수 있습니다. 이는 특정 상황에서 작동할 수 있지만 맹목적으로 를 수락하고 처리하는 것은 보안 위험입니다 SupplierID. 예를 들어 GridView는 미국의 공급업체만 나열합니다. 그러나 가 라디오 단추에서 직접 전달되는 경우 SupplierID 장난스러운 사용자가 포스트백에 다시 전송된 값을 조작하지 SupplierID 못하게 하려면 어떻게 해야 할까요? 행 인덱스를 로 value사용한 다음 컬렉션에서 DataKeys 온 포스트백을 가져오 SupplierID 면 사용자가 GridView 행 중 SupplierID 하나와 연결된 값 중 하나만 사용하고 있는지 확인할 수 있습니다.

이 이벤트 처리기 코드를 추가한 후 잠시 시간을 내어 브라우저에서 페이지를 테스트합니다. 먼저 그리드에서 한 번에 하나의 라디오 단추만 선택할 수 있습니다. 그러나 라디오 단추를 선택하고 단추 중 하나를 클릭하면 포스트백이 발생하고 라디오 단추가 모두 초기 상태로 되돌리기(즉, 포스트백 시 선택한 라디오 단추가 더 이상 선택되지 않음) 이 문제를 해결하려면 이벤트 처리기가 포스트백에서 전송된 선택한 라디오 단추 인덱스를 검사하고 행 인덱스 일치 항목의 내보낸 태그에 특성을 추가 checked="checked" 하도록 이벤트 처리기를 보강 RowCreated 해야 합니다.

포스트백이 발생하면 브라우저는 선택한 라디오 단추의 및 value 를 다시 name 보냅니다. 값을 사용하여 프로그래밍 방식으로 검색 Request.Form["name"]할 수 있습니다. 속성은 Request.Form 양식 변수를 나타내는 을 제공합니다NameValueCollection. 양식 변수는 웹 페이지에 있는 양식 필드의 이름과 값이며, 포스트백이 계속될 때마다 웹 브라우저에서 다시 전송됩니다. GridView에서 라디오 단추의 렌더링된 name 특성은 이므로 SuppliersGroup웹 페이지가 다시 게시되면 브라우저가 다른 양식 필드와 함께 웹 서버로 다시 전송 SuppliersGroup=valueOfSelectedRadioButton 됩니다. 그런 다음, Request.Form["SuppliersGroup"]를 사용하여 속성에서 Request.Form 이 정보에 액세스할 수 있습니다.

이벤트 처리기뿐만 아니라 단추 웹 컨트롤에 대한 이벤트 처리기에서 RowCreatedClick 선택한 라디오 단추 인덱스를 결정해야 하므로 라디오 단추가 선택되지 않은 경우 를 반환 -1 하는 코드 숨김 클래스와 라디오 단추 중 하나가 선택된 경우 선택한 인덱스에 속성을 추가 SuppliersSelectedIndex 해 보겠습니다.

private int SuppliersSelectedIndex
{
    get
    {
        if (string.IsNullOrEmpty(Request.Form["SuppliersGroup"]))
            return -1;
        else
            return Convert.ToInt32(Request.Form["SuppliersGroup"]);
    }
}

이 속성을 추가하면 가 와 같을 checked="checked"SuppliersSelectedIndex 이벤트 처리기에 태그를 RowCreated 추가하는 것을 알고 있습니다.e.Row.RowIndex 다음 논리를 포함하도록 이벤트 처리기를 업데이트합니다.

protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Grab a reference to the Literal control
        Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
        // Output the markup except for the "checked" attribute
        output.Text = string.Format(
            @"<input type="radio" name="SuppliersGroup" " +
            @"id="RowSelector{0}" value="{0}"", e.Row.RowIndex);
        // See if we need to add the "checked" attribute
        if (SuppliersSelectedIndex == e.Row.RowIndex)
            output.Text += @" checked="checked"";
        // Add the closing tag
        output.Text += " />";
    }
}

이 변경으로 선택한 라디오 단추는 포스트백 후에 선택된 상태로 유지됩니다. 이제 선택한 라디오 단추를 지정할 수 있으므로 페이지를 처음 방문했을 때 첫 번째 GridView 행의 라디오 단추가 선택되도록 동작을 변경할 수 있습니다(기본적으로 현재 동작인 라디오 단추가 선택되지 않음). 기본적으로 첫 번째 라디오 단추를 선택하려면 문을 로 if (SuppliersSelectedIndex == e.Row.RowIndex || (!Page.IsPostBack && e.Row.RowIndex == 0))변경 if (SuppliersSelectedIndex == e.Row.RowIndex) 하기만 하면됩니다.

이 시점에서 단일 GridView 행을 선택하고 포스트백에서 기억할 수 있는 그룹화된 라디오 단추 열을 GridView에 추가했습니다. 다음 단계는 선택한 공급자가 제공하는 제품을 표시하는 것입니다. 4단계에서는 선택한 SupplierID을 따라 사용자를 다른 페이지로 리디렉션하는 방법을 알아보세요. 5단계에서는 선택한 공급업체 제품을 동일한 페이지의 GridView에 표시하는 방법을 살펴보겠습니다.

참고

TemplateField(이 긴 3단계의 초점)를 사용하는 대신 적절한 사용자 인터페이스 및 기능을 렌더링하는 사용자 지정 DataControlField 클래스를 만들 수 있습니다. 클래스는 DataControlField BoundField, CheckBoxField, TemplateField 및 기타 기본 제공 GridView 및 DetailsView 필드가 파생되는 기본 클래스입니다. 사용자 지정 DataControlField 클래스를 만들면 선언적 구문을 사용하여 라디오 단추 열을 추가할 수 있으며 다른 웹 페이지 및 기타 웹 애플리케이션의 기능을 훨씬 쉽게 복제할 수 있습니다.

그러나 ASP.NET 사용자 지정 컴파일된 컨트롤을 만든 적이 있다면 상당한 양의 레그워크가 필요하고 신중하게 처리해야 하는 미묘한 및 에지 케이스를 수반한다는 것을 알고 있습니다. 따라서 지금은 라디오 단추 열을 사용자 지정 DataControlField 클래스로 구현하는 것을 포기하고 TemplateField 옵션을 고수합니다. 향후 자습서에서는 사용자 지정 DataControlField 클래스를 만들고, 사용하고, 배포하는 방법을 살펴볼 수 있습니다.

4단계: 개별 페이지에 선택한 공급업체 제품 표시

사용자가 GridView 행을 선택한 후에는 선택한 공급업체 제품을 표시해야 합니다. 경우에 따라 이러한 제품을 별도의 페이지에 표시하고, 다른 경우에는 동일한 페이지에서 제품을 표시하는 것을 선호할 수 있습니다. 먼저 별도의 페이지에서 제품을 표시하는 방법을 살펴보겠습니다. 5단계에서는 선택한 공급업체 제품을 표시하기 위해 GridView를 RadioButtonField.aspx 에 추가하는 방법을 살펴보겠습니다.

현재 페이지 ListProductsSendToProducts에 두 개의 단추 웹 컨트롤이 있습니다. SendToProducts 단추를 클릭하면 사용자를 로 보내려고 합니다~/Filtering/ProductsForSupplierDetails.aspx. 이 페이지는 두 페이지에 걸친 마스터/세부 정보 필터링 자습서에서 만들어졌으며 라는 SupplierIDquerystring 필드를 통해 전달되는 공급자 SupplierID 의 제품을 표시합니다.

이 기능을 제공하려면 Button 이벤트에 Click 대한 SendToProducts 이벤트 처리기를 만듭니다. 3단계에서는 라디오 단추가 SuppliersSelectedIndex 선택된 행의 인덱스가 반환되는 속성을 추가했습니다. 해당 SupplierID 는 GridView의 DataKeys 컬렉션에서 검색할 수 있으며 사용자는 를 사용하여 Response.Redirect("url")~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID 보낼 수 있습니다.

protected void SendToProducts_Click(object sender, EventArgs e)
{
    // Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
    int supplierID = 
        Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
    Response.Redirect(
        "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" 
        + supplierID);
    }
}

이 코드는 GridView에서 라디오 단추 중 하나가 선택된 한 멋지게 작동합니다. 처음에 GridView에 라디오 단추가 선택되어 있지 않고 사용자가 단추를 SuppliersSelectedIndex-1클릭하면 SendToProducts 가 되므로 가 컬렉션의 DataKeys 인덱스 범위를 벗어났기 때문에 -1 예외가 throw됩니다. 그러나 GridView에서 첫 번째 라디오 단추를 처음 선택하도록 3단계에서 설명한 대로 이벤트 처리기를 업데이트 RowCreated 하기로 결정한 경우에는 문제가 되지 않습니다.

값을 -1수용 SuppliersSelectedIndex 하려면 GridView 위의 페이지에 레이블 웹 컨트롤을 추가합니다. 속성을 ID , 해당 CssClass 속성으로 EnableViewStatefalseWarningVisible 설정하고 속성을 로 설정하고 속성을 로 설정하고 해당 Text 속성을 표에서 공급자를 선택하세요.ChooseSupplierMsg CSS 클래스 Warning 는 텍스트를 빨간색, 기울임꼴, 굵게, 큰 글꼴로 표시하고 에 Styles.css정의됩니다. 및 Visible 속성을 로 설정 EnableViewState 하면 컨트롤의 Visible 속성false이 프로그래밍 방식으로 로 설정된 true포스트백만 제외하고 Label은 렌더링되지 않습니다.

GridView 위에 레이블 웹 컨트롤 추가

그림 13: GridView 위에 레이블 웹 컨트롤 추가(전체 크기 이미지를 보려면 클릭)

다음으로, 이벤트 처리기를 보강 Click 하여 이 0보다 작은 경우 SuppliersSelectedIndex Label을 표시 ChooseSupplierMsg 하고, 그렇지 않으면 사용자를 ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID 리디렉션합니다.

protected void SendToProducts_Click(object sender, EventArgs e)
{
    // make sure one of the radio buttons has been selected
    if (SuppliersSelectedIndex < 0)
        ChooseSupplierMsg.Visible = true;
    else
    {
        // Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
        int supplierID = 
            Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
        Response.Redirect(
            "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" 
            + supplierID);
    }
}

GridView에서 공급자를 선택하기 전에 브라우저에서 페이지를 방문하고 단추를 클릭합니다 SendToProducts . 그림 14와 같이 레이블이 ChooseSupplierMsg 표시됩니다. 다음으로 공급업체를 선택하고 단추를 클릭합니다 SendToProducts . 그러면 선택한 공급업체에서 제공하는 제품이 나열된 페이지로 이동됩니다. 그림 15는 빅풋 양조장 공급업체가 선택된 페이지를 보여줍니다 ProductsForSupplierDetails.aspx .

공급자가 선택되지 않은 경우 SelectSupplierMsg 레이블이 표시됩니다.

그림 14: ChooseSupplierMsg 공급자가 선택되지 않은 경우 레이블이 표시됩니다(전체 크기 이미지를 보려면 클릭).

선택한 공급업체의 제품이 ProductsForSupplierDetails.aspx 표시됨

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

5단계: 동일한 페이지에 선택한 공급업체 제품 표시

4단계에서는 사용자를 다른 웹 페이지로 보내 선택한 공급업체 제품을 표시하는 방법을 알아보았습니다. 또는 선택한 공급업체의 제품을 동일한 페이지에 표시할 수 있습니다. 이를 설명하기 위해 다른 GridView를 에 RadioButtonField.aspx 추가하여 선택한 공급업체 제품을 표시합니다.

공급업체를 선택한 후에만 이 제품의 GridView를 표시하도록 하려면 GridView 아래에 Suppliers 패널 웹 컨트롤을 추가하고 해당 컨트롤을 IDProductsBySupplierPanel 로 설정하고 해당 Visible 속성을 false로 설정합니다. 패널 내에서 선택한 공급자에 대한 제품 텍스트와 라는 ProductsBySupplierGridView를 추가합니다. GridView의 스마트 태그에서 라는 새 ObjectDataSource ProductsBySupplierDataSource에 바인딩하도록 선택합니다.

ProductsBySupplier GridView를 새 ObjectDataSource에 바인딩

그림 16: GridView를 ProductsBySupplier 새 ObjectDataSource에 바인딩(전체 크기 이미지를 보려면 클릭)

다음으로, 클래스를 사용하도록 ObjectDataSource를 구성합니다 ProductsBLL . 선택한 공급자가 제공한 제품만 검색하려고 하므로 ObjectDataSource에서 메서드를 호출 GetProductsBySupplierID(supplierID) 하여 해당 데이터를 검색하도록 지정합니다. UPDATE, INSERT 및 DELETE 탭의 드롭다운 목록에서 (없음)을 선택합니다.

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

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

UPDATE, INSERT 및 DELETE 탭에서 Drop-Down Lists (없음)으로 설정합니다.

그림 18: UPDATE, INSERT 및 DELETE 탭에서 Drop-Down Lists (없음)으로 설정합니다(전체 크기 이미지를 보려면 클릭).

SELECT, UPDATE, INSERT 및 DELETE 탭을 구성한 후 다음을 클릭합니다. 메서드는 GetProductsBySupplierID(supplierID) 입력 매개 변수를 예상하므로 데이터 원본 만들기 마법사에서 매개 변수 값의 원본을 지정하라는 메시지를 표시합니다.

매개 변수 값의 원본을 지정하는 데 몇 가지 옵션이 있습니다. 기본 Parameter 개체를 사용하고 ObjectDataSource Selecting 이벤트 SuppliersSelectedIndex 처리기의 Parameter DefaultValue 속성에 속성 값을 프로그래밍 방식으로 할당할 수 있습니다. ObjectDataSource의 매개 변수에 값을 프로그래밍 방식으로 할당하는 방법에 대한 새로 고침은 프로그래밍 방식으로 ObjectDataSource의 매개 변수 값 설정 자습서를 참조하세요.

또는 ControlParameter를 사용하고 GridView의 SelectedValue 속성을 참조할 Suppliers 수 있습니다(그림 19 참조). GridView의 SelectedValue 속성은 속성에 DataKey 해당하는 SelectedIndex값을 반환합니다. 이 옵션이 작동하려면 단추를 클릭할 때 ListProducts GridView 속성을 SelectedIndex 선택한 행으로 프로그래밍 방식으로 설정해야 합니다. 추가 혜택으로, 를 설정 SelectedIndex하여 선택한 레코드는 테마(노란색 배경)에 SelectedRowStyleDataWebControls 정의된 를 사용합니다.

ControlParameter를 사용하여 GridView의 SelectedValue를 매개 변수 원본으로 지정

그림 19: ControlParameter를 사용하여 GridView의 SelectedValue를 매개 변수 원본으로 지정합니다(전체 크기 이미지를 보려면 클릭).

마법사를 완료하면 Visual Studio에서 제품의 데이터 필드에 대한 필드를 자동으로 추가합니다. , CategoryNameUnitPrice BoundFields를 ProductName제외한 모든 항목을 제거하고 속성을 Product, Category 및 Price로 변경 HeaderText 합니다. 해당 값이 UnitPrice 통화로 형식이 지정되도록 BoundField를 구성합니다. 이러한 변경을 수행한 후 Panel, GridView 및 ObjectDataSource의 선언적 태그는 다음과 같이 표시됩니다.

<asp:Panel runat="server" ID="ProductsBySupplierPanel" Visible="False">
    <h3>
        Products for the Selected Supplier</h3>
    <p>
        <asp:GridView ID="ProductsBySupplier" runat="server" 
            AutoGenerateColumns="False" DataKeyNames="ProductID"
            DataSourceID="ProductsBySupplierDataSource" EnableViewState="False">
            <Columns>
                <asp:BoundField DataField="ProductName" HeaderText="Product" 
                    SortExpression="ProductName" />
                <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                    ReadOnly="True" SortExpression="CategoryName" />
                <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                    HeaderText="Price" HtmlEncode="False" 
                    SortExpression="UnitPrice" />
            </Columns>
        </asp:GridView>
        <asp:ObjectDataSource ID="ProductsBySupplierDataSource" runat="server" 
            OldValuesParameterFormatString="original_{0}"
            SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
            <SelectParameters>
                <asp:ControlParameter ControlID="Suppliers" Name="supplierID" 
                    PropertyName="SelectedValue" Type="Int32" />
            </SelectParameters>
        </asp:ObjectDataSource>
    </p>
</asp:Panel>

이 연습을 완료하려면 GridView의 SelectedIndex 속성을 로 설정하고 단추를 클릭할 SelectedSuppliersIndexProductsBySupplierPanelListProducts Panel 속성을 Visibletrue 설정해야 합니다. 이렇게 하려면 Button Web 컨트롤의 Click 이벤트에 대한 ListProducts 이벤트 처리기를 만들고 다음 코드를 추가합니다.

protected void ListProducts_Click(object sender, EventArgs e)
{
    // make sure one of the radio buttons has been selected
    if (SuppliersSelectedIndex < 0)
    {
        ChooseSupplierMsg.Visible = true;
        ProductsBySupplierPanel.Visible = false;
    }
    else
    {
        // Set the GridView's SelectedIndex
        Suppliers.SelectedIndex = SuppliersSelectedIndex;
        // Show the ProductsBySupplierPanel panel
        ProductsBySupplierPanel.Visible = true;
    }
}

GridView ChooseSupplierMsg 에서 공급업체를 선택하지 않은 경우 레이블이 표시되고 패널이 ProductsBySupplierPanel 숨겨집니다. 그렇지 않으면 공급자가 선택된 ProductsBySupplierPanel 경우 가 표시되고 GridView의 SelectedIndex 속성이 업데이트됩니다.

그림 20은 Bigfoot Breweries 공급업체가 선택되고 페이지에 제품 표시 단추를 클릭한 후의 결과를 보여 줍니다.

Bigfoot 양조장에서 제공하는 제품은 동일한 페이지에 나열됩니다.

그림 20: Bigfoot 양조장에서 제공하는 제품이 동일한 페이지에 나열됩니다(전체 크기 이미지를 보려면 클릭).

요약

세부 정보 세부 정보 보기와 함께 선택 가능한 마스터 GridView를 사용하여 마스터/세부 정보 자습서에서 설명한 대로 속성이 로 설정된 trueCommandField ShowSelectButton 를 사용하여 GridView에서 레코드를 선택할 수 있습니다. 그러나 CommandField는 해당 단추를 일반 푸시 단추, 링크 또는 이미지로 표시합니다. 다른 행 선택 사용자 인터페이스는 각 GridView 행에 라디오 단추 또는 확인란을 제공하는 것입니다. 이 자습서에서는 라디오 단추 열을 추가하는 방법을 검토했습니다.

아쉽게도 라디오 단추 열을 추가하는 것은 예상대로 간단하거나 간단하지 않습니다. 단추를 클릭할 때 추가할 수 있는 기본 제공 RadioButtonField가 없으며 TemplateField 내에서 RadioButton 웹 컨트롤을 사용하면 고유한 문제 집합이 도입됩니다. 결국 이러한 인터페이스를 제공하려면 사용자 지정 DataControlField 클래스를 만들거나 이벤트 중에 RowCreated 적절한 HTML을 TemplateField에 삽입해야 합니다.

라디오 단추 열을 추가하는 방법을 살펴보면서 확인란 열을 추가하는 데 주의를 기울이겠습니다. 확인란의 열을 사용하면 사용자가 하나 이상의 GridView 행을 선택한 다음 선택한 모든 행(예: 웹 기반 전자 메일 클라이언트에서 전자 메일 집합을 선택한 다음 선택한 모든 전자 메일을 삭제하도록 선택)에 대해 일부 작업을 수행할 수 있습니다. 다음 자습서에서는 이러한 열을 추가하는 방법을 살펴보겠습니다.

행복한 프로그래밍!

저자 정보

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.