Sdílet prostřednictvím


Přizpůsobení rozhraní pro úpravy prvku DataList (VB)

Scott Mitchell

Stáhnout PDF

V tomto kurzu vytvoříme bohatší rozhraní pro úpravy DataList, které obsahuje DropDownLists a CheckBox.

Úvod

Revizní a webové ovládací prvky v Ovládacích prvcích DataList s EditItemTemplate definují jeho upravitelné rozhraní. Ve všech editovatelných příkladech DataList, které jsme zatím prozkoumali, se editovatelné rozhraní skládají z webových ovládacích prvků TextBox. V předchozím kurzu jsme vylepšili uživatelské prostředí pro úpravy a čas přidáním ověřovacích ovládacích prvků.

Lze EditItemTemplate dále rozšířit tak, aby zahrnovaly jiné webové ovládací prvky než TextBox, například DropDownLists, RadioButtonLists, Calendars atd. Stejně jako u textových polí při přizpůsobení rozhraní pro úpravy tak, aby zahrnovalo další webové ovládací prvky, použijte následující kroky:

  1. Přidejte ovládací prvek Web do souboru EditItemTemplate.
  2. Pomocí syntaxe vazby dat přiřaďte odpovídající hodnotu datového pole příslušné vlastnosti.
  3. V obslužné rutině UpdateCommand události programově přejděte k hodnotě webového ovládacího prvku a předejte ji do příslušné metody BLL.

V tomto kurzu vytvoříme bohatší rozhraní pro úpravy DataList, které obsahuje DropDownLists a CheckBox. Konkrétně vytvoříme Seznam dat se seznamem informací o produktu a povolíme aktualizaci názvu produktu, dodavatele, kategorie a ukončeného stavu (viz obrázek 1).

Rozhraní pro úpravy obsahuje textové pole, dva rozevírací seznamy a zaškrtávací políčko.

Obrázek 1: Rozhraní pro úpravy obsahuje textové pole, dva rozevírací seznamy a zaškrtávací políčko (kliknutím zobrazíte obrázek v plné velikosti).

Krok 1: Zobrazení informací o produktu

Než budeme moct vytvořit upravitelné rozhraní DataList s, musíme nejprve sestavit rozhraní jen pro čtení. Začněte otevřením CustomizedUI.aspx stránky ze EditDeleteDataList složky a v Návrháři přidejte na stránku DataList a nastavte jeho ID vlastnost na Products. Z inteligentní značky DataList vytvořte nový ObjectDataSource. Pojmenujte tento nový ObjectDataSource ProductsDataSource a nakonfigurujte ho tak, aby načítal data z ProductsBLL metody třídy.GetProducts Stejně jako v předchozích upravitelných kurzech DataList aktualizujeme upravené informace o produktu tak, že přejdeme přímo na vrstvu obchodní logiky. Proto nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné).

Nastavte rozevírací seznamy KARET UPDATE, INSERT a DELETE na (Žádné).

Obrázek 2: Nastavení rozevíracích seznamů karet UPDATE, INSERT a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)

Po nakonfigurování ObjectDataSource vytvoří Visual Studio výchozí hodnotu ItemTemplate pro DataList, která vypíše název a hodnotu pro všechna vrácená datová pole. ItemTemplate Upravte tak, aby šablona vypisovala název produktu v <h4> prvku spolu s názvem kategorie, názvem dodavatele, cenou a ukončeným stavem. Kromě toho přidejte tlačítko Upravit a ujistěte se, že jeho CommandName vlastnost je nastavena na Upravit. Deklarativní kód pro mé ItemTemplate následující:

<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>

Výše uvedená značka uvádí informace o produktu pomocí <nadpisu h4> pro název výrobku a čtyřsloupce <table> pro zbývající pole. Třídy ProductPropertyLabel CSS ProductPropertyValue definované v Styles.css, byly popsány v předchozích kurzech. Obrázek 3 znázorňuje průběh zobrazení v prohlížeči.

Zobrazí se název, dodavatel, kategorie, ukončený stav a cena každého produktu.

Obrázek 3: Zobrazí se název, dodavatel, kategorie, ukončený stav a cena každého produktu (kliknutím zobrazíte obrázek v plné velikosti).

Krok 2: Přidání webových ovládacích prvků do rozhraní pro úpravy

Prvním krokem při vytváření přizpůsobeného rozhraní pro úpravy DataList je přidání potřebných webových ovládacích prvků do EditItemTemplate. Konkrétně potřebujeme rozevírací seznam pro kategorii, další pro dodavatele a CheckBox pro ukončený stav. Vzhledem k tomu, že cena produktu není v tomto příkladu upravitelná, můžeme ji dál zobrazovat pomocí ovládacího prvku Label Web.

Pokud chcete upravit rozhraní pro úpravy, klikněte na odkaz Upravit šablony z inteligentní značky DataList s a zvolte EditItemTemplate možnost z rozevíracího seznamu. Přidejte rozevírací seznam do EditItemTemplate seznamu a nastavte jeho ID hodnotu Categories.

Přidání rozevíracího seznamu pro kategorie

Obrázek 4: Přidání rozevíracího seznamu pro kategorie (kliknutím zobrazíte obrázek v plné velikosti)

Dále z inteligentní značky DropDownList vyberte možnost Zvolit zdroj dat a vytvořte nový ObjectDataSource s názvem CategoriesDataSource. Nakonfigurujte tento ObjectDataSource tak, aby používal metodu CategoriesBLL třídy s GetCategories() (viz obrázek 5). Dále Průvodce konfigurací zdroje dat DropDownList s vyzve k zadání datových polí, která se mají použít pro každou ListItem s Text a Value vlastnosti. V rozevíracím seznamu se CategoryName zobrazí datové pole a použije se CategoryID jako hodnota, jak je znázorněno na obrázku 6.

Vytvoření nového objektu ObjectDataSource s názvem CategoriesDataSource

Obrázek 5: Vytvoření nového objektu ObjectDataSource s názvem CategoriesDataSource (kliknutím zobrazíte obrázek s plnou velikostí)

Konfigurace polí zobrazovaných a hodnot rozevíracího seznamu

Obrázek 6: Konfigurace polí zobrazení a hodnot rozevíracího seznamu (kliknutím zobrazíte obrázek s plnou velikostí)

Opakujte tuto řadu kroků a vytvořte rozevírací seznam pro dodavatele. ID Nastavte pro tento DropDownList Suppliers a pojmenujte jeho ObjectDataSource SuppliersDataSource.

Po přidání dvou rozevíracích seznamů přidejte CheckBox pro ukončený stav a TextBox pro název produktu. Nastavte hodnoty ID checkBox a TextBox na Discontinued hodnotu a ProductNamev uvedeném pořadí. Přidejte RequiredFieldValidator, abyste zajistili, že uživatel zadá hodnotu pro název produktu.

Nakonec přidejte tlačítka Aktualizovat a Zrušit. Nezapomeňte, že u těchto dvou tlačítek je nezbytné, aby jejich CommandName vlastnosti byly nastaveny na Aktualizovat a Zrušit.

Nebojte se rozložení rozhraní pro úpravy, ale chcete. Rozhodl(a) jsem se použít stejné rozložení se čtyřmi sloupci <table> z rozhraní jen pro čtení, jak ukazuje následující deklarativní syntaxe a snímek obrazovky:

<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"
                    DataSourceID="SuppliersDataSource" DataTextField="CompanyName"
                    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>

Rozhraní pro úpravy je rozloženo jako rozhraní jen pro čtení.

Obrázek 7: Rozhraní pro úpravy je rozloženo jako rozhraní jen pro čtení (kliknutím zobrazíte obrázek s plnou velikostí).

Krok 3: Vytvoření obslužných rutin událostí EditCommand a CancelCommand

V současné době neexistuje syntaxe EditItemTemplate vazby dat (s výjimkou UnitPriceLabel, která byla zkopírována přes doslovné doslovné písmeno ItemTemplate). Syntaxi vazby dat přidáme prozatím, ale nejprve vytvoříme obslužné rutiny událostí pro dataList s EditCommand a CancelCommand události. Vzpomeňte si, že odpovědnost EditCommand obslužné rutiny události je vykreslit rozhraní pro úpravy položky DataList, jejíž tlačítko Upravit bylo kliknuto, zatímco CancelCommand úloha s je vrátit DataList do stavu předběžné úpravy.

Vytvořte tyto dva obslužné rutiny událostí a nechte je použít následující kód:

Protected Sub Products_EditCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.EditCommand
    ' Set the DataList's EditItemIndex property to the
    ' index of the DataListItem that was clicked
    Products.EditItemIndex = e.Item.ItemIndex
    ' Rebind the data to the DataList
    Products.DataBind()
End Sub
Protected Sub Products_CancelCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.CancelCommand
    ' Set the DataList's EditItemIndex property to -1
    Products.EditItemIndex = -1
    ' Rebind the data to the DataList
    Products.DataBind()
End Sub

Když jsou tyto dva obslužné rutiny událostí na místě, kliknutím na tlačítko Upravit zobrazíte rozhraní pro úpravy a kliknutím na tlačítko Storno vrátíte upravenou položku do režimu jen pro čtení. Obrázek 8 znázorňuje Seznam dat po kliknutí na tlačítko Upravit pro Chef Anton s Gumbo Mix. Vzhledem k tomu, že jsme ještě přidali syntaxi vazby dat do rozhraní pro úpravy, ProductName textbox je prázdný, Discontinued zaškrtávací políčko nezaškrtnuté a první položky vybrané z Categories rozevíracích seznamů a Suppliers rozevírací seznamy.

Snímek obrazovky s objektem DataList EditItemTemplate po přidání obslužných rutin událostí EditCommand a CancelCommand a výběru tlačítka Upravit

Obrázek 8: Kliknutím na tlačítko Upravit zobrazíte rozhraní pro úpravy (kliknutím zobrazíte obrázek v plné velikosti).

Krok 4: Přidání syntaxe vazby dat do rozhraní pro úpravy

Abychom měli rozhraní pro úpravy zobrazované aktuální hodnoty produktu, musíme použít syntaxi vazby dat k přiřazení hodnot datových polí příslušným hodnotám webového ovládacího prvku. Syntaxi vazby dat lze použít prostřednictvím Návrháře tak, že přejdete na obrazovku Upravit šablony a vyberete odkaz Upravit vazby dat z inteligentních značek webových ovládacích prvků. Alternativně lze syntaxi vazby dat přidat přímo do deklarativního kódu.

Přiřaďte hodnotu datového ProductName pole vlastnosti ProductName TextBox s Text , CategoryID hodnoty datových SupplierID polí k Categories vlastnostem a Suppliers DropDownLists SelectedValue a hodnotu datového Discontinued pole vlastnosti Discontinued CheckBox s Checked . Po provedení těchto změn buď prostřednictvím Návrháře, nebo přímo prostřednictvím deklarativní revize, znovu se podívejte na stránku v prohlížeči a klikněte na tlačítko Upravit pro Chef Anton s Gumbo Mix. Jak ukazuje obrázek 9, syntaxe vazby dat přidala aktuální hodnoty do TextBox, DropDownLists a CheckBox.

Snímek obrazovky s objektem DataList EditItemTemplate po přidání syntaxe datové vazby a výběru tlačítka Upravit

Obrázek 9: Kliknutím na tlačítko Upravit zobrazíte rozhraní pro úpravy (kliknutím zobrazíte obrázek v plné velikosti).

Krok 5: Uložení změn uživatele v obslužné rutině události UpdateCommand

Když uživatel upraví produkt a klikne na tlačítko Aktualizovat, dojde k zpětnému odeslání a událost DataList s UpdateCommand se aktivuje. V obslužné rutině události potřebujeme přečíst hodnoty z webových ovládacích prvků v EditItemTemplate ovládacích prvcích a rozhraní s BLL, abychom aktualizovali produkt v databázi. Jak jsme viděli v předchozích kurzech, ProductID aktualizovaný produkt je přístupný prostřednictvím DataKeys kolekce. Uživatelsky zadaná pole jsou přístupná programovým odkazem na webové ovládací prvky pomocí FindControl("controlID"), jak ukazuje následující kód:

Protected Sub Products_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.UpdateCommand
    If Not Page.IsValid Then
        Exit Sub
    End If
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(Products.DataKeys(e.Item.ItemIndex))
    ' Read in the product name and price values
    Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
    Dim categories As DropDownList=CType(e.Item.FindControl("Categories"), DropDownList)
    Dim suppliers As DropDownList = CType(e.Item.FindControl("Suppliers"), DropDownList)
    Dim discontinued As CheckBox = CType(e.Item.FindControl("Discontinued"), CheckBox)
    Dim productNameValue As String = Nothing
    If productName.Text.Trim().Length > 0 Then
        productNameValue = productName.Text.Trim()
    End If
    Dim categoryIDValue As Integer = Convert.ToInt32(categories.SelectedValue)
    Dim supplierIDValue As Integer = Convert.ToInt32(suppliers.SelectedValue)
    Dim discontinuedValue As Boolean = discontinued.Checked
    ' Call the ProductsBLL's UpdateProduct method...
    Dim productsAPI As New ProductsBLL()
    productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue, _
        discontinuedValue, productID)
    ' Revert the DataList back to its pre-editing state
    Products.EditItemIndex = -1
    Products.DataBind()
End Sub

Kód začíná konzultacem s Page.IsValid vlastností, aby se zajistilo, že všechny ověřovací ovládací prvky na stránce jsou platné. Pokud Page.IsValid ano True, upravená hodnota produktu ProductID se načítá z DataKeys kolekce a webové ovládací prvky pro zadávání dat v souboru EditItemTemplate jsou odkazovány prostřednictvím kódu programu. Dále se hodnoty z těchto webových ovládacích prvků načtou do proměnných, které se pak předají do příslušného UpdateProduct přetížení. Po aktualizaci dat se datový seznam vrátí do stavu předběžné úpravy.

Poznámka:

Vynechal(a) jsem logiku zpracování výjimek přidanou v kurzu Zpracování výjimek na úrovni BLL a DAL, aby byl kód a tento příklad zaměřený na tento příklad. Jako cvičení přidejte tuto funkci po dokončení tohoto kurzu.

Krok 6: Zpracování hodnot NULL CategoryID a SupplierID

Databáze Northwind umožňuje hodnoty NULL pro Products tabulky CategoryID a SupplierID sloupce. Naše rozhraní pro úpravy ale v současné době neobsahuje NULL hodnoty. Pokud se pokusíme upravit produkt, který má NULL hodnotu pro jeho CategoryID nebo SupplierID sloupce, zobrazí ArgumentOutOfRangeException se chybová zpráva podobná: Kategorie má hodnotu SelectedValue, protože v seznamu položek neexistuje. V současné době také neexistuje způsob, jak změnit kategorii produktu nebo hodnotu dodavatele z hodnoty,NULL která není hodnota na NULL hodnotu.

Abychom podpořili NULL hodnoty pro kategorii a dodavatele DropDownLists, musíme přidat další ListItem. Rozhodl jsem se použít (None) jako Text hodnotu pro toto ListItem, ale můžete ho změnit na něco jiného (například prázdný řetězec), pokud chcete. Nakonec nezapomeňte nastavit DropDownLists AppendDataBoundItems na True; pokud to zapomenete, kategorie a dodavatelé vázané na DropDownList přepíší staticky přidané ListItem.

Po provedení těchto změn by měl kód DropDownLists v sadě DataList s EditItemTemplate vypadat nějak takto:

<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>

Poznámka:

Statické ListItem hodnoty lze přidat do rozevíracího seznamu prostřednictvím Návrháře nebo přímo prostřednictvím deklarativní syntaxe. Při přidávání položky DropDownList představující hodnotu databáze NULL nezapomeňte přidat ListItem prostřednictvím deklarativní syntaxe. Pokud v Návrháři ListItem použijete Editor kolekcí, vygenerovaná deklarativní syntaxe Value vynechá nastavení úplně při přiřazení prázdného řetězce a vytvoří deklarativní značky jako: <asp:ListItem>(None)</asp:ListItem>. I když to může vypadat neškodně, chybějící Value způsobí, že DropDownList použije Text hodnotu vlastnosti na svém místě. To znamená, že pokud je tato NULL ListItem možnost vybrána, hodnota (None) se pokusí přiřadit k poli s daty produktu (CategoryID nebo SupplierID, v tomto kurzu), což způsobí výjimku. Explicitním nastavením Value=""NULL se hodnota přiřadí k poli s daty produktu při NULL ListItem výběru.

Chvilku si prohlédněte průběh v prohlížeči. Při úpravě produktu mějte na paměti, že Categories na začátku rozevíracího seznamu mají oba Suppliers rozevírací seznamy možnost (None).

Mezi kategorie a rozevírací seznamy dodavatelů patří možnost (Žádná).

Obrázek 10: Rozevírací Categories Suppliers seznamy obsahují možnost (Žádné) (kliknutím zobrazíte obrázek v plné velikosti).

Pokud chcete uložit možnost (None) jako hodnotu databáze NULL , musíme se vrátit do obslužné rutiny UpdateCommand události. categoryIDValue Změňte hodnoty a supplierIDValue proměnné na celá čísla s možnou hodnotou null a přiřaďte jim jinou hodnotu než Nothing pouze v případě, že dropDownList s SelectedValue není prázdný řetězec:

Dim categoryIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(categories.SelectedValue) Then
    categoryIDValue = Convert.ToInt32(categories.SelectedValue)
End If
Dim supplierIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(suppliers.SelectedValue) Then
    supplierIDValue = Convert.ToInt32(suppliers.SelectedValue)
End If

Při této změně bude hodnota Nothing předána UpdateProduct do metody BLL, pokud uživatel vybral možnost (None) z některého z rozevíracích seznamů, který odpovídá hodnotě NULL databáze.

Shrnutí

V tomto kurzu jsme viděli, jak vytvořit složitější rozhraní pro úpravy DataList, které zahrnovalo tři různé vstupní webové ovládací prvky TextBox, dva Rozevírací seznamy a CheckBox spolu s ověřovacími ovládacími prvky. Při vytváření rozhraní pro úpravy jsou kroky stejné bez ohledu na používané webové ovládací prvky: začněte přidáním webových ovládacích prvků do objektu DataList s EditItemTemplate; pomocí syntaxe vazby dat přiřaďte odpovídající hodnoty datových polí odpovídajícími vlastnostmi webového ovládacího prvku; a v UpdateCommand obslužné rutině události programově přistupovat k webovým ovládacím prvkům a jejich příslušným vlastnostem, předání jejich hodnot do BLL.

Při vytváření rozhraní pro úpravy, ať už se skládá pouze z textových polí nebo kolekce různých webových ovládacích prvků, nezapomeňte správně zpracovat hodnoty databáze NULL . Při účtování NULL je nutné, abyste nejen správně zobrazili existující NULL hodnotu v rozhraní pro úpravy, ale také, že nabízíte prostředky pro označení hodnoty jako NULL. U dropDownLists v DataLists to obvykle znamená přidání statické ListItem , jehož Value vlastnost je explicitně nastavena na prázdný řetězec (Value="") a přidání bit kódu do UpdateCommand obslužné rutiny události určit, zda byla vybrána nebo ne NULL``ListItem .

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí recenzenti tohoto kurzu byli Dennis Patterson, David Suru a Randy Schmidt. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.