Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
door Scott Mitchell
In deze zelfstudie maken we een uitgebreidere bewerkingsinterface voor de DataList, een interface met vervolgkeuzelijsten en een selectievakje.
Introductie
De opmaak en webbesturingselementen van de DataListEditItemTemplate definiëren de bewerkbare interface. In alle bewerkbare DataList-voorbeelden die we tot nu toe hebben onderzocht, is de bewerkbare interface samengesteld uit webbesturingselementen voor tekstvakken. In de voorgaande handleiding hebben we de gebruikerservaring tijdens het bewerken verbeterd door validatiecontroles toe te voegen.
Het EditItemTemplate kan verder worden uitgebreid met andere webbesturingselementen dan het tekstvak, zoals DropDownLists, RadioButtonLists, Agenda's, enzovoort. Net als bij tekstvaken voert u bij het aanpassen van de bewerkingsinterface om andere webbesturingselementen op te nemen de volgende stappen uit:
- Voeg het Web-besturingselement toe aan het
EditItemTemplate. - Gebruik de syntaxis van databinding om de bijbehorende gegevensveldwaarde toe te wijzen aan de juiste eigenschap.
- In de
UpdateCommandgebeurtenishandler krijgt u programmatisch toegang tot de waarde van de webcontrole en geeft u deze door aan de juiste BLL-methode.
In deze zelfstudie maken we een uitgebreidere bewerkingsinterface voor de DataList, een interface met vervolgkeuzelijsten en een selectievakje. In het bijzonder maken we een DataList waarin productgegevens worden vermeld en waarmee de productnaam, leverancier, categorie en stopgezette status kunnen worden bijgewerkt (zie afbeelding 1).
Afbeelding 1: De bewerkingsinterface bevat een tekstvak, twee vervolgkeuzelijsten en een selectievakje (klik om de volledige afbeelding weer te geven)
Stap 1: Productgegevens weergeven
Voordat we de bewerkbare interface van DataList kunnen maken, moeten we eerst de alleen-lezeninterface bouwen. Begin met het openen van de CustomizedUI.aspx pagina vanuit de EditDeleteDataList map en voeg vanuit de ontwerpfunctie een DataList toe aan de pagina, waarbij de eigenschap wordt ingesteld ID op Products. Maak vanuit de infotag van DataList een nieuwe ObjectDataSource. Geef deze nieuwe ObjectDataSource ProductsDataSource een naam en configureer deze om gegevens op te halen uit de ProductsBLL klassemethode GetProducts . Net als bij de vorige bewerkbare DataList-zelfstudies werken we de informatie van het bewerkte product bij door rechtstreeks naar de bedrijfslogicalaag te gaan. Stel de vervolgkeuzelijsten op de tabbladen UPDATE, INSERT en DELETE in op (Geen).
Afbeelding 2: Stel de tabbladen UPDATE, INSERT en DELETE Drop-Down Lijsten in op (Geen) (Klik om de volledige afbeelding weer te geven)
Nadat u de ObjectDataSource hebt geconfigureerd, maakt Visual Studio een standaardwaarde ItemTemplate voor de DataList met de naam en waarde voor elk van de geretourneerde gegevensvelden. Pas de sjabloon zo ItemTemplate aan dat de productnaam in een <h4> element wordt vermeld, samen met de categorienaam, leveranciernaam, prijs en stopgezette status. Voeg bovendien een knop Bewerken toe en zorg ervoor dat CommandName de eigenschap is ingesteld op Bewerken. De declaratieve opmaak voor mijn ItemTemplate volgt:
<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>
In de bovenstaande markering worden de productgegevens beschreven met behulp van een <h4-kop> voor de productnaam en een vierkolom <table> voor de resterende velden. De ProductPropertyLabel en ProductPropertyValue CSS-klassen, gedefinieerd in Styles.css, zijn besproken in de vorige zelfstudies. In afbeelding 3 ziet u de voortgang wanneer u deze bekijkt via een browser.
Afbeelding 3: De naam, leverancier, categorie, stopgezette status en prijs van elk product wordt weergegeven (klik om de volledige afbeelding weer te geven)
Stap 2: de webbesturingselementen toevoegen aan de bewerkingsinterface
De eerste stap bij het bouwen van de aangepaste Bewerkingsinterface voor DataList is het toevoegen van de benodigde webbesturingselementen aan de EditItemTemplate. In het bijzonder hebben we een vervolgkeuzelijst nodig voor de categorie, een andere voor de leverancier en een selectievakje voor de stopgezette status. Omdat de prijs van het product in dit voorbeeld niet kan worden bewerkt, kunnen we deze blijven weergeven met behulp van een labelwebbesturingselement.
Als u de bewerkingsinterface wilt aanpassen, klikt u op de koppeling Sjablonen bewerken in de infotag van DataList en kiest u de EditItemTemplate optie in de vervolgkeuzelijst. Voeg een DropDownList toe aan de EditItemTemplate en stel de ID in op Categories.
Afbeelding 4: Een vervolgkeuzelijst toevoegen voor de categorieën (klik om de afbeelding op volledige grootte weer te geven)
Selecteer vervolgens in de smarttag van de DropDownList de optie Gegevensbron kiezen en maak een nieuwe ObjectDataSource met de naam CategoriesDataSource. Configureer deze ObjectDataSource om de CategoriesBLL klasse en de GetCategories() methode te gebruiken (zie afbeelding 5). Vervolgens vraagt de Gegevensbronconfiguratiewizard van de vervolgkeuzelijst naar welke gegevensvelden moeten worden gebruikt voor elke ListItem s Text- en Value-eigenschap. Laat de vervolgkeuzelijst het CategoryName gegevensveld weergeven en de CategoryID waarde gebruiken, zoals wordt weergegeven in afbeelding 6.
Afbeelding 5: Een nieuwe ObjectDataSource maken met de naam CategoriesDataSource (klik om de afbeelding op volledige grootte weer te geven)
Afbeelding 6: De weergave- en waardevelden van de vervolgkeuzelijsten configureren (klik om de volledige afbeelding weer te geven)
Herhaal deze reeks stappen om een vervolgkeuzelijst voor de leveranciers te maken. Stel de ID voor deze DropDownList in op Suppliers en geef de objectdatabron SuppliersDataSourceeen naam.
Nadat u de twee vervolgkeuzelijsten hebt toegevoegd, voegt u een selectievakje toe voor de stopgezette status en een tekstvak voor de naam van het product. Stel de ID s voor het selectievakje en tekstvak Discontinued in op respectievelijk ProductName. Voeg een RequiredFieldValidator toe om ervoor te zorgen dat de gebruiker een waarde biedt voor de productnaam.
Voeg ten slotte de knoppen Bijwerken en Annuleren toe. Houd er rekening mee dat voor deze twee knoppen het noodzakelijk is dat hun CommandName eigenschappen zijn ingesteld op Respectievelijk Bijwerken en Annuleren.
Voel je vrij om de bewerkingsinterface op de door jou gewenste wijze in te delen. Ik heb ervoor gekozen om dezelfde indeling met vier kolommen <table> te gebruiken vanuit de interface met het kenmerk Alleen-lezen, zoals de volgende declaratieve syntaxis en schermafbeelding illustreert:
<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>
Afbeelding 7: De bewerkingsinterface is ingedeeld zoals de Read-Only-interface (klik om de afbeelding op volledige grootte weer te geven)
Stap 3: de gebeurtenis-handlers EditCommand en CancelCommand maken
Op dit moment is er geen syntaxis voor databinding in de EditItemTemplate (behalve de UnitPriceLabel, die is gekopieerd van de exacte bewoordingen van de ItemTemplate). We voegen de syntaxis van de gegevensbinding tijdelijk toe, maar eerst gaan we de gebeurtenis-handlers maken voor de DataList-s EditCommand en CancelCommand -gebeurtenissen. Zoals u zich herinnert, is de verantwoordelijkheid van de EditCommand gebeurtenishandler om de bewerkingsinterface weer te geven voor het DataList-item waarop de knop Bewerken is geklikt, terwijl de CancelCommand taak is om de DataList terug te brengen naar de status vooraf bewerken.
Maak deze twee gebeurtenis-handlers en laat ze de volgende code gebruiken:
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
Met deze twee gebeurtenis-handlers ingesteld, zorgt klikken op de knop Bewerken ervoor dat de bewerkingsinterface wordt weergegeven en wordt het bewerkte item teruggezet naar de modus Alleen-lezen als op de knop Annuleren wordt gedrukt. Afbeelding 8 toont de DataList nadat op de knop Bewerken is geklikt voor Chef Anton s Gumbo Mix. Omdat we nog geen gegevensbindingsyntaxis aan de bewerkingsinterface hebben toegevoegd, is het ProductName tekstvak leeg, het Discontinued selectievakje niet aangevinkt en de eerste items die zijn geselecteerd in de Categories en Suppliers vervolgkeuzelijst.
Afbeelding 8: Als u op de knop Bewerken klikt, wordt de bewerkingsinterface weergegeven (klik om de volledige afbeelding weer te geven)
Stap 4: De DataBinding-syntaxis toevoegen aan de bewerkingsinterface
Om de bewerkingsinterface de huidige productwaarden weer te geven, moeten we de syntaxis van de gegevensbinding gebruiken om de waarden van het gegevensveld toe te wijzen aan de juiste webbeheerwaarden. De syntaxis van de gegevensbinding kan worden toegepast via de ontwerpfunctie door naar het scherm Sjablonen bewerken te gaan en de koppeling DataBindings bewerken te selecteren in de infolabels voor webbesturingselementen. De syntaxis van de gegevensbinding kan ook rechtstreeks aan de declaratieve markering worden toegevoegd.
Wijs de waarde van het ProductName gegevensveld toe aan de ProductName eigenschap TekstvakText, de CategoryID en SupplierID gegevensveldwaarden aan de Categories eigenschappen en Suppliers DropDownLists SelectedValue en de waarde van het Discontinued gegevensveld aan de Discontinued eigenschap Selectievakje.Checked Nadat u deze wijzigingen hebt aangebracht, ofwel via de Designer of rechtstreeks via de declaratieve markup, bezoekt u de pagina opnieuw via een browser en klikt u op de knop Bewerken voor Chef Anton's Gumbo Mix. Zoals in afbeelding 9 wordt weergegeven, heeft de syntaxis van de gegevensbinding de huidige waarden toegevoegd aan het tekstvak, de vervolgkeuzelijsten en het selectievakje.
Afbeelding 9: Als u op de knop Bewerken klikt, wordt de bewerkingsinterface weergegeven (klik om de volledige afbeelding weer te geven)
Stap 5: De wijzigingen van de gebruiker opslaan in de gebeurtenis-handler UpdateCommand
Wanneer de gebruiker een product bewerkt en op de knop Bijwerken klikt, treedt er een postback op en wordt het DataList-evenement UpdateCommand geactiveerd. In de gebeurtenishandler moeten we de waarden van de webcontrols in de EditItemTemplate lezen en communiceren met de BLL om het product in de database bij te werken. Zoals we in de vorige tutorials hebben gezien, is het ProductID bijgewerkte product toegankelijk via de DataKeys collectie. De door de gebruiker ingevoerde velden worden geopend door programmatisch te verwijzen naar de webbesturingselementen met behulp van FindControl("controlID"), zoals in de volgende code wordt weergegeven:
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
De code begint door de Page.IsValid eigenschap te raadplegen om ervoor te zorgen dat alle validatiebesturingselementen op de pagina geldig zijn. Als Page.IsValidTrue is, wordt de bewerkte productwaarde ProductID gelezen uit de DataKeys verzameling en worden de webbesturingselementen voor gegevensinvoer in de EditItemTemplate programmatig aangeroepen. Vervolgens worden de waarden van deze webbesturingselementen ingelezen in variabelen die vervolgens worden doorgegeven aan de juiste UpdateProduct overbelasting. Na het bijwerken van de gegevens wordt de DataList teruggezet naar de oorspronkelijke staat.
Opmerking
Ik heb de logica voor het afhandelen van uitzonderingen die is toegevoegd aan de zelfstudie BLL- en DAL-Level Exceptions weggelaten om de code en dit voorbeeld overzichtelijk te houden. Als oefening voegt u deze functionaliteit toe nadat u deze tutorial hebt voltooid.
Stap 6: NULL CategoryID- en Leveranciers-ID-waarden verwerken
De Northwind-database biedt NULL waarden voor de Products tabel en CategoryIDSupplierID kolommen. De bewerkingsinterface biedt momenteel echter geen ruimte voor NULL waarden. Als we proberen een product te bewerken met een NULL waarde voor de bijbehorende CategoryID waarde of SupplierID kolommen, krijgen we een ArgumentOutOfRangeException foutbericht dat lijkt op: 'Categories' heeft een SelectedValue die ongeldig is omdat deze niet bestaat in de lijst met items. Er is momenteel ook geen manier om een productcategorie of leverancierwaarde te wijzigen van een niet-waardeNULL in een NULL waarde.
Ter ondersteuning van NULL waarden voor de categorie en vervolgkeuzelijsten van leveranciers moeten we een extra ListItemwaarde toevoegen. Ik heb ervoor gekozen om (Geen) als waarde Text hiervoor ListItemte gebruiken, maar u kunt deze desgewenst wijzigen in iets anders (zoals een lege tekenreeks). Vergeet ten slotte niet om de DropDownLists AppendDataBoundItemsTruein te stellen op ; als u dit vergeet, overschrijven de categorieën en leveranciers die zijn gebonden aan de DropDownList de statisch toegevoegde ListItem.
Nadat u deze wijzigingen hebt aangebracht, moeten de vervolgkeuzelijsten in de DataList s EditItemTemplate er ongeveer als volgt uitzien:
<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>
Opmerking
Statische ListItem s kunnen worden toegevoegd aan een vervolgkeuzelijst via de ontwerpfunctie of rechtstreeks via de declaratieve syntaxis. Wanneer u een DropDownList-item toevoegt om een databasewaarde NULL weer te geven, zorg er dan voor dat u dit doet via de declaratieve syntaxis met ListItem. Als u de ListItem verzamelingseditor in de ontwerpfunctie gebruikt, laat de gegenereerde declaratieve syntaxis de Value instelling helemaal weg wanneer een lege tekenreeks wordt toegewezen, waardoor declaratieve markeringen worden gemaakt zoals: <asp:ListItem>(None)</asp:ListItem> Hoewel dit er ongevaarlijk uitziet, zorgt het ontbreken Value ervoor dat de DropDownList de Text eigenschapswaarde op zijn plaats gebruikt. Dit betekent dat als dit NULLListItem is geselecteerd, er zal worden getracht de waarde (Geen) toe te wijzen aan het gegevensveld van het product (CategoryID of SupplierID, in deze handleiding), wat zal resulteren in een fout. Door expliciet in te stellen Value="", wordt er een NULL waarde toegewezen aan het gegevensveld van het product wanneer de NULLListItem waarde is geselecteerd.
Neem even de tijd om onze voortgang via een browser te bekijken. Wanneer u een product bewerkt, moet u er rekening mee houden dat de vervolgkeuzelijsten Categories en Suppliers beide aan het begin een optie (Geen) hebben.
Afbeelding 10: De Categories en Suppliers dropDownLists bevatten een optie (Geen) (Klik om de volledige afbeelding weer te geven)
Als u de optie (Geen) wilt opslaan als een databasewaarde NULL , moet u terugkeren naar de UpdateCommand gebeurtenis-handler. Wijzig de categoryIDValue waarden en supplierIDValue variabelen zodat ze nullable gehele getallen zijn en wijs ze een andere waarde toe dan Nothing alleen als vervolgkeuzelijst s SelectedValue geen lege tekenreeks is:
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
Met deze wijziging wordt een waarde van Nothing doorgegeven aan de UpdateProduct BLL-methode als de gebruiker de optie (Geen) heeft geselecteerd in een van de vervolgkeuzelijsten, wat overeenkomt met een NULL databasewaarde.
Samenvatting
In deze zelfstudie hebben we gezien hoe u een complexere bewerkingsinterface voor DataList maakt met drie verschillende invoerwebbesturingselementen voor een tekstvak, twee vervolgkeuzelijsten en een selectievakje, samen met validatiebesturingselementen. Bij het bouwen van de bewerkingsinterface zijn de stappen hetzelfde, ongeacht de webbesturingselementen die worden gebruikt: begin met het toevoegen van de webbesturingselementen aan de DataList s EditItemTemplate; gebruik de syntaxis van gegevensbinding om de bijbehorende gegevensveldwaarden met de juiste eigenschappen van het webbesturingselement toe te wijzen; en in de UpdateCommand gebeurtenishandler krijgt u programmatisch toegang tot de webbesturingselementen en de bijbehorende eigenschappen, hun waarden doorgeven aan de BLL.
Wanneer u een bewerkingsinterface maakt, ongeacht of deze bestaat uit alleen tekstvakken of een verzameling verschillende webbesturingselementen, moet u databasewaarden NULL correct verwerken. Wanneer u rekening houdt met NULL s, is het noodzakelijk dat u niet alleen een bestaande NULL waarde correct weergeeft in de bewerkingsinterface, maar ook dat u een manier biedt om een waarde als NULLte markeren. Voor DropDownLists in DataLists betekent dit meestal dat u een statische ListItem eigenschap toevoegt waarvan Value de eigenschap expliciet is ingesteld op een lege tekenreeks (Value="") en een beetje code toevoegt aan de UpdateCommand gebeurtenis-handler om te bepalen of de NULL``ListItem eigenschap al dan niet is geselecteerd.
Veel plezier met programmeren!
Over de auteur
Scott Mitchell, auteur van zeven ASP/ASP.NET-boeken en oprichter van 4GuysFromRolla.com, werkt sinds 1998 met Microsoft-webtechnologieën. Scott werkt als onafhankelijk consultant, trainer en schrijver. Zijn laatste boek is Sams Teach Yourself ASP.NET 2.0 in 24 uur. Hij kan worden bereikt op mitchell@4GuysFromRolla.com.
Speciale dank aan
Deze tutorialreeks is beoordeeld door veel behulpzame beoordelers. Hoofdreviewers voor deze zelfstudie waren Dennis Patterson, David Suru en Randy Schmidt. Bent u geïnteresseerd in het bekijken van mijn aanstaande MSDN-artikelen? Zo ja, laat iets van je horen via mitchell@4GuysFromRolla.com.