다음을 통해 공유


DataList의 편집 인터페이스 사용자 지정(C#)

스콧 미첼

PDF 다운로드

이 자습서에서는 DropDownList 및 CheckBox를 포함하는 DataList에 대한 보다 풍부한 편집 인터페이스를 만듭니다.

소개

DataList의 EditItemTemplate 태그 및 웹 컨트롤은 편집 가능한 인터페이스를 정의합니다. 지금까지 살펴본 모든 편집 가능한 DataList 예제에서 편집 가능한 인터페이스는 TextBox 웹 컨트롤로 구성되었습니다. 이전 자습서에서는 유효성 검사 컨트롤을 추가하여 편집 시간 사용자 환경을 개선했습니다.

EditItemTemplate DropDownLists, RadioButtonLists, 일정 등과 같은 TextBox 이외의 웹 컨트롤을 포함하도록 더 확장할 수 있습니다. TextBoxes와 마찬가지로 다른 웹 컨트롤을 포함하도록 편집 인터페이스를 사용자 지정할 때 다음 단계를 사용합니다.

  1. 에 웹 컨트롤을 추가합니다 EditItemTemplate.
  2. 데이터 바인딩 구문을 사용하여 해당 데이터 필드 값을 적절한 속성에 할당합니다.
  3. UpdateCommand 이벤트 처리기에서 프로그래밍 방식으로 웹 컨트롤 값에 액세스하여 적절한 BLL 메서드에 전달합니다.

이 자습서에서는 DropDownList 및 CheckBox를 포함하는 DataList에 대한 보다 풍부한 편집 인터페이스를 만듭니다. 특히 제품 정보를 나열하고 제품 이름, 공급업체, 범주 및 중단된 상태를 업데이트할 수 있도록 하는 DataList를 만듭니다(그림 1 참조).

편집 인터페이스에는 TextBox, 두 개의 DropDownList 및 CheckBox가 포함됩니다.

그림 1: 편집 인터페이스에는 TextBox, 두 개의 DropDownList 및 CheckBox가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

1단계: 제품 정보 표시

DataList의 편집 가능한 인터페이스를 만들려면 먼저 읽기 전용 인터페이스를 빌드해야 합니다. 먼저 폴더에서 페이지를 열고 CustomizedUI.aspx 디자이너에서 EditDeleteDataList DataList를 페이지에 추가하고 해당 ID 속성을 Products.로 설정합니다. DataList의 스마트 태그에서 새 ObjectDataSource를 만듭니다. 이 새 ObjectDataSource ProductsDataSource 의 이름을 지정하고 클래스의 GetProducts 메서드에서 ProductsBLL 데이터를 검색하도록 구성합니다. 이전 편집 가능한 DataList 자습서와 마찬가지로 비즈니스 논리 계층으로 직접 이동하여 편집된 제품 정보를 업데이트합니다. 따라서 UPDATE, INSERT 및 DELETE 탭의 드롭다운 목록을 (없음)으로 설정합니다.

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

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

ObjectDataSource를 구성한 후 Visual Studio는 반환된 각 데이터 필드의 이름과 값을 나열하는 DataList에 대한 기본값 ItemTemplate 을 만듭니다. 템플릿이 ItemTemplate 범주 이름, 공급업체 이름 <h4> , 가격 및 중단된 상태와 함께 요소의 제품 이름을 나열할 수 있도록 수정합니다. 또한 편집 단추를 추가하여 해당 CommandName 속성이 편집으로 설정되어 있는지 확인합니다. 내 ItemTemplate 선언적 태그는 다음과 같습니다.

<ItemTemplate>
    <h4>
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' />
    </h4>
    <table border="0">
        <tr>
            <td class="ProductPropertyLabel">Category:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="CategoryNameLabel" runat="server"
                    Text='<%# Eval("CategoryName") %>' />
            </td>
            <td class="ProductPropertyLabel">Supplier:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="SupplierNameLabel" runat="server"
                    Text='<%# Eval("SupplierName") %>' />
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Discontinued:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="DiscontinuedLabel" runat="server"
                    Text='<%# Eval("Discontinued") %>' />
            </td>
            <td class="ProductPropertyLabel">Price:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
            </td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:Button runat="Server" ID="EditButton"
                    Text="Edit" CommandName="Edit" />
            </td>
        </tr>
    </table>
    <br />
</ItemTemplate>

위의 태그는 제품 이름에 h4 제목을 사용하고 나머지 필드에는 4>열 <table> 을 사용하여 <제품 정보를 배치합니다. ProductPropertyLabel 정의된 Styles.cssCSS 클래스 및 ProductPropertyValue CSS 클래스는 이전 자습서에서 설명했습니다. 그림 3은 브라우저를 통해 볼 때 진행 상황을 보여 줍니다.

각 제품의 이름, 공급업체, 범주, 중단된 상태 및 가격이 표시됩니다.

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

2단계: 편집 인터페이스에 웹 컨트롤 추가

사용자 지정된 DataList 편집 인터페이스를 빌드하는 첫 번째 단계는 필요한 웹 컨트롤을 에 추가하는 것입니다 EditItemTemplate. 특히 범주에 대한 DropDownList, 공급업체의 다른 항목 및 중단된 상태에 대한 CheckBox가 필요합니다. 이 예제에서는 제품 가격을 편집할 수 없으므로 레이블 웹 컨트롤을 사용하여 계속 표시할 수 있습니다.

편집 인터페이스를 사용자 지정하려면 DataList의 스마트 태그에서 템플릿 편집 링크를 클릭하고 드롭다운 목록에서 옵션을 선택합니다 EditItemTemplate . DropDownList를 EditItemTemplate 에 추가하고 해당 ID 드롭다운 목록을 .로 Categories설정합니다.

범주에 대한 DropDownList 추가

그림 4: 범주에 대한 DropDownList 추가(전체 크기 이미지를 보려면 클릭)

그런 다음 DropDownList의 스마트 태그에서 데이터 원본 선택 옵션을 선택하고 새 ObjectDataSource를 만듭니다 CategoriesDataSource. 클래스 메서드 GetCategories() 를 사용하도록 이 ObjectDataSource를 CategoriesBLL 구성합니다(그림 5 참조). 다음으로 DropDownList의 데이터 원본 구성 마법사는 각 ListItem Text s 및 Value 속성에 사용할 데이터 필드를 묻는 메시지를 표시합니다. 그림 6과 CategoryName 같이 DropDownList에 데이터 필드가 표시되고 값으로 사용 CategoryID 하게 합니다.

CategoriesDataSource라는 새 ObjectDataSource 만들기

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

DropDownList의 표시 및 값 필드 구성

그림 6: DropDownList의 표시 및 값 필드 구성(전체 크기 이미지를 보려면 클릭)

이 일련의 단계를 반복하여 공급업체에 대한 DropDownList를 만듭니다. 이 DropDownList의 ID 이름을 ObjectDataSourceSuppliersDataSourceSuppliers 설정하고 이름을 지정합니다.

두 DropDownLists를 추가한 후 중단된 상태의 CheckBox와 제품 이름에 대한 TextBox를 추가합니다. ID 각각 CheckBox 및 TextBox에 대한 s를 Discontinued ProductName설정합니다. RequiredFieldValidator를 추가하여 사용자가 제품 이름에 대한 값을 제공하는지 확인합니다.

마지막으로 업데이트 및 취소 단추를 추가합니다. 이 두 단추의 경우 해당 CommandName 속성이 각각 업데이트 및 취소로 설정되는 것이 중요합니다.

원하는 편집 인터페이스를 자유롭게 배치할 수 있습니다. 다음 선언적 구문과 스크린샷에서 보여 주듯이 읽기 전용 인터페이스에서 동일한 4열 <table> 레이아웃을 사용하도록 선택했습니다.

<EditItemTemplate>
    <h4>
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' />
    </h4>
    <table border="0">
        <tr>
            <td class="ProductPropertyLabel">Name:</td>
            <td colspan="3" class="ProductPropertyValue">
                <asp:TextBox runat="server" ID="ProductName" Width="90%" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
                    ControlToValidate="ProductName"
                    ErrorMessage="You must enter a name for the product."
                    runat="server">*</asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Category:</td>
            <td class="ProductPropertyValue">
                <asp:DropDownList ID="Categories" runat="server"
                    DataSourceID="CategoriesDataSource"
                    DataTextField="CategoryName" DataValueField="CategoryID" />
            </td>
            <td class="ProductPropertyLabel">Supplier:</td>
            <td class="ProductPropertyValue">
                <asp:DropDownList ID="Suppliers" DataTextField="CompanyName"
                    DataSourceID="SuppliersDataSource"
                    DataValueField="SupplierID" runat="server" />
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Discontinued:</td>
            <td class="ProductPropertyValue">
                <asp:CheckBox runat="server" id="Discontinued" />
            </td>
            <td class="ProductPropertyLabel">Price:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
            </td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:Button runat="Server" ID="UpdateButton" CommandName="Update"
                    Text="Update" />
                 
                <asp:Button runat="Server" ID="CancelButton" CommandName="Cancel"
                    Text="Cancel" CausesValidation="False" />
            </td>
        </tr>
    </table>
    <br />
    <asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"
        TypeName="CategoriesBLL">
    </asp:ObjectDataSource>
    <asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers"
        TypeName="SuppliersBLL">
    </asp:ObjectDataSource>
</EditItemTemplate>

편집 인터페이스는 읽기 전용 인터페이스처럼 배치됩니다.

그림 7: 편집 인터페이스가 읽기 전용 인터페이스처럼 배치됨(전체 크기 이미지를 보려면 클릭)

3단계: EditCommand 및 CancelCommand 이벤트 처리기 만들기

현재는 데이터 바인딩 구문이 없습니다(축자 위에 ItemTemplate복사된 구문 EditItemTemplate 제외UnitPriceLabel). 데이터 바인딩 구문을 잠시 추가하지만 먼저 DataList EditCommandCancelCommand 이벤트에 대한 이벤트 처리기를 만들어 보겠습니다. 이벤트 처리기의 책임 EditCommand 은 편집 단추를 클릭한 DataList 항목에 대한 편집 인터페이스를 렌더링하는 반면 CancelCommand , 작업은 DataList를 사전 편집 상태로 반환하는 것입니다.

이러한 두 이벤트 처리기를 만들고 다음 코드를 사용하도록 합니다.

protected void Products_EditCommand(object source, DataListCommandEventArgs e)
{
    // Set the DataList's EditItemIndex property and rebind the data
    Products.EditItemIndex = e.Item.ItemIndex;
    Products.DataBind();
}
protected void Products_CancelCommand(object source, DataListCommandEventArgs e)
{
    // Return to DataList to its pre-editing state
    Products.EditItemIndex = -1;
    Products.DataBind();
}

이 두 이벤트 처리기가 준비되면 편집 단추를 클릭하면 편집 인터페이스가 표시되고 취소 단추를 클릭하면 편집된 항목이 읽기 전용 모드로 반환됩니다. 그림 8에서는 안톤 셰프의 검보 믹스에 대한 편집 단추를 클릭한 후의 DataList를 보여 줍니다. 아직 편집 인터페이스 ProductName 에 데이터 바인딩 구문을 추가하지 않았으므로 TextBox가 비어 있고, CheckBox가 Discontinued 선택되지 않았으며, DropDownLists에서 Categories Suppliers 선택한 첫 번째 항목이 있습니다.

EditCommand 및 CancelCommand 이벤트 처리기가 추가되고 편집 단추가 선택된 후 DataList EditItemTemplate을 보여 주는 스크린샷

그림 8: 편집 단추를 클릭하면 편집 인터페이스가 표시됩니다(전체 크기 이미지를 보려면 클릭).

4단계: 편집 인터페이스에 DataBinding 구문 추가

편집 인터페이스에 현재 제품 값이 표시되도록 하려면 데이터 바인딩 구문을 사용하여 데이터 필드 값을 적절한 웹 컨트롤 값에 할당해야 합니다. 템플릿 편집 화면으로 이동하고 웹 컨트롤 스마트 태그에서 DataBindings 편집 링크를 선택하여 디자이너를 통해 데이터 바인딩 구문을 적용할 수 있습니다. 또는 데이터 바인딩 구문을 선언적 태그에 직접 추가할 수 있습니다.

ProductName 데이터 필드 값을 ProductName TextBox Text 속성, CategoryID 데이터 필드 값 CategoriesSupplierID DropDownLists SelectedValue 속성에 할당하고 Suppliers Discontinued, 데이터 필드 값을 CheckBox Checked 속성에 Discontinued 할당합니다. 디자이너를 통해 또는 선언적 태그를 통해 직접 변경한 후 브라우저를 통해 페이지를 다시 방문하고 Anton의 Gumbo Mix 셰프에 대한 편집 단추를 클릭합니다. 그림 9와 같이 데이터 바인딩 구문은 현재 값을 TextBox, DropDownLists 및 CheckBox에 추가했습니다.

DataBinding 구문이 추가되고 편집 단추가 선택된 후 DataList EditItemTemplate을 보여 주는 스크린샷

그림 9: 편집 단추를 클릭하면 편집 인터페이스가 표시됩니다(전체 크기 이미지를 보려면 클릭).

5단계: UpdateCommand 이벤트 처리기에서 사용자 변경 내용 저장

사용자가 제품을 편집하고 업데이트 단추를 클릭하면 포스트백이 발생하고 DataList 이벤트가 UpdateCommand 발생합니다. 이벤트 처리기에서 데이터베이스의 제품을 업데이트하려면 BLL과 인터페이스의 웹 컨트롤 EditItemTemplate 에서 값을 읽어야 합니다. 이전 자습서에서 보았듯이 업데이트된 ProductID 제품의 컬렉션에 액세스할 수 있습니다 DataKeys . 다음 코드와 같이 사용자가 입력한 필드는 다음 코드와 같이 웹 컨트롤을 프로그래밍 FindControl("controlID")방식으로 참조하여 액세스합니다.

protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
    // Make sure the page is valid...
    if (!Page.IsValid)
        return;
    // Read in the ProductID from the DataKeys collection
    int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
    // Read in the product name and price values
    TextBox productName = (TextBox)e.Item.FindControl("ProductName");
    DropDownList categories = (DropDownList)e.Item.FindControl("Categories");
    DropDownList suppliers = (DropDownList)e.Item.FindControl("Suppliers");
    CheckBox discontinued = (CheckBox)e.Item.FindControl("Discontinued");
    string productNameValue = null;
    if (productName.Text.Trim().Length > 0)
        productNameValue = productName.Text.Trim();
    int categoryIDValue = Convert.ToInt32(categories.SelectedValue);
    int supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
    bool discontinuedValue = discontinued.Checked;
    // Call the ProductsBLL's UpdateProduct method...
    ProductsBLL productsAPI = new ProductsBLL();
    productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue,
                              discontinuedValue, productID);
    // Revert the DataList back to its pre-editing state
    Products.EditItemIndex = -1;
    Products.DataBind();
}

코드는 페이지의 모든 유효성 검사 컨트롤이 유효한지 확인하기 위해 속성을 참조 Page.IsValid 하여 시작합니다. 이 True경우 Page.IsValid 편집된 제품의 ProductID 값이 컬렉션에서 DataKeys 읽혀지고 웹 컨트롤의 EditItemTemplate 데이터 항목이 프로그래밍 방식으로 참조됩니다. 다음으로, 이러한 웹 컨트롤의 값을 변수로 읽은 다음 적절한 UpdateProduct 오버로드로 전달합니다. 데이터를 업데이트한 후 DataList는 사전 편집 상태로 반환됩니다.

참고 항목

코드와 이 예제를 집중적으로 유지하기 위해 BLL 및 DAL 수준 예외 처리 자습서에 추가 된 예외 처리 논리를 생략했습니다. 연습으로 이 자습서를 완료한 후 이 기능을 추가합니다.

6단계: NULL CategoryID 및 SupplierID 값 처리

Northwind 데이터베이스는 테이블 CategoryIDSupplierID 열에 Products 대한 NULL 값을 허용합니다. 그러나 편집 인터페이스는 현재 값을 수용 NULL 하지 않습니다. 해당 CategoryID 항목 또는 SupplierIDArgumentOutOfRangeException 에 대한 값이 있는 NULL 제품을 편집하려고 하면 '범주'에 항목 목록에 없기 때문에 잘못된 SelectedValue가 있다는 오류 메시지가 표시됩니다. 또한 현재 제품의 범주 또는 공급업체 값을 비NULL값에서 1로 변경할 수 있는 NULL 방법은 없습니다.

범주 및 공급업체 DropDownLists에 대한 값을 지원 NULL 하려면 추가 ListItem항목을 추가해야 합니다. 이 값ListItem으로 Text (없음)을 사용하도록 선택했지만 원하는 경우 다른 항목(예: 빈 문자열)으로 변경할 수 있습니다. 마지막으로 DropDownList를 AppendDataBoundItems True설정해야 합니다. 드롭다운 목록을 잊은 경우 DropDownList에 바인딩된 범주 및 공급업체는 정적으로 추가 ListItem된 항목을 덮어씁니다.

이러한 변경을 수행한 후 DataList의 EditItemTemplate DropDownLists 태그는 다음과 유사하게 표시됩니다.

<asp:DropDownList ID="Categories" DataSourceID="CategoriesDataSource"
    DataTextField="CategoryName" DataValueField="CategoryID" runat="server"
    SelectedValue='<%# Eval("CategoryID") %>' AppendDataBoundItems="True">
    <asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
...
<asp:DropDownList ID="Suppliers" DataSourceID="SuppliersDataSource"
    DataTextField="CompanyName" DataValueField="SupplierID" runat="server"
    SelectedValue='<%# Eval("SupplierID") %>' AppendDataBoundItems="True">
    <asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>

참고 항목

정적 ListItem s는 디자이너를 통해 또는 선언적 구문을 통해 직접 DropDownList에 추가할 수 있습니다. 데이터베이스 NULL 값을 나타내는 DropDownList 항목을 추가할 때 선언적 구문을 통해 추가 ListItem 해야 합니다. 디자이너에서 컬렉션 편집기를 사용하는 ListItem 경우 생성된 선언적 구문은 빈 문자열이 할당될 때 설정을 모두 생략 Value 하고 다음과 같은 <asp:ListItem>(None)</asp:ListItem>선언적 태그를 만듭니다. 이로 인해 무해해 보일 수 있지만 누락 Value 된 경우 DropDownList는 Text 해당 위치에서 속성 값을 사용합니다. 즉, 이 NULL ListItem 옵션을 선택하면 값(없음)이 제품 데이터 필드(CategoryID 또는 SupplierID이 자습서에서)에 할당되어 예외가 발생합니다. 명시적으로 설정 Value=""NULL 하면 값이 선택될 때 NULL ListItem 제품 데이터 필드에 할당됩니다.

잠시 브라우저를 통해 진행 상황을 확인하세요. 제품을 Categories 편집할 때 DropDownList와 Suppliers DropDownList는 모두 DropDownList의 시작 부분에 (없음) 옵션이 있습니다.

범주 및 공급업체 드롭다운 목록에는 (없음) 옵션이 포함됩니다.

그림 10: DropDownLists에는 Categories Suppliers (없음) 옵션이 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

(없음) 옵션을 데이터베이스 NULL 값으로 저장하려면 이벤트 처리기로 UpdateCommand 돌아가야 합니다. categoryIDValue 변수 및 supplierIDValue 변수를 nullable 정수로 변경하고 DropDownList SelectedValue 가 빈 문자열이 아닌 경우에만 값을 Nothing 할당합니다.

int? categoryIDValue = null;
if (!string.IsNullOrEmpty(categories.SelectedValue))
    categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int? supplierIDValue = null;
if (!string.IsNullOrEmpty(suppliers.SelectedValue))
    supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);

이 변경으로 사용자가 데이터베이스 값 NothingUpdateProduct 해당하는 드롭다운 목록 중 하나에서 (없음) 옵션을 선택한 경우 값이 BLL 메서드로 NULL 전달됩니다.

요약

이 자습서에서는 TextBox, 두 개의 DropDownList 및 CheckBox와 유효성 검사 컨트롤의 세 가지 입력 웹 컨트롤을 포함하는 보다 복잡한 DataList 편집 인터페이스를 만드는 방법을 알아보았습니다. 편집 인터페이스를 빌드할 때는 사용 중인 웹 컨트롤에 관계없이 단계가 동일합니다. 먼저 DataList EditItemTemplate에 웹 컨트롤을 추가하고, 데이터 바인딩 구문을 사용하여 해당 데이터 필드 값을 적절한 웹 컨트롤 속성으로 할당하고, 이벤트 처리기에서 UpdateCommand 프로그래밍 방식으로 웹 컨트롤 및 해당 속성에 액세스합니다. 값을 BLL에 전달합니다.

편집 인터페이스를 만들 때 TextBoxs만 구성하든 다른 웹 컨트롤의 컬렉션으로 구성되든 데이터베이스 NULL 값을 올바르게 처리해야 합니다. s를 계산 NULL 할 때는 편집 인터페이스에 기존 NULL 값을 올바르게 표시할 뿐만 아니라 값을 NULL로 표시하기 위한 수단을 제공해야 합니다. DataLists의 DropDownLists의 경우 일반적으로 속성이 Value 빈 문자열(Value="")로 명시적으로 설정된 정적 ListItem 을 추가하고 이벤트 처리기에 약간의 코드를 UpdateCommand 추가하여 선택되었는지 여부를 NULL``ListItem 확인합니다.

행복한 프로그래밍!

작성자 정보

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

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 데니스 패터슨, 데이비드 수루, 랜디 슈미트였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 선을 놓습니다 mitchell@4GuysFromRolla.com.