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 ziet u hoe u de methoden Insert(), Update() en Delete() van ObjectDataSource toewijst aan de methoden van BLL-klassen en hoe u de besturingselementen GridView, DetailsView en FormView configureert om mogelijkheden voor gegevenswijziging te bieden.
Introductie
In de afgelopen zelfstudies hebben we onderzocht hoe u gegevens op een ASP.NET pagina kunt weergeven met behulp van de besturingselementen GridView, DetailsView en FormView. Deze besturingselementen werken gewoon met gegevens die eraan worden verstrekt. Deze besturingselementen hebben doorgaans toegang tot gegevens met behulp van een gegevensbroncontrole, zoals de ObjectDataSource. We hebben gezien hoe de ObjectDataSource fungeert als proxy tussen de ASP.NET-pagina en de onderliggende gegevens. Wanneer een GridView gegevens moet weergeven, roept deze de methode van ObjectDataSource Select()
aan, die op zijn beurt een methode aanroept van onze Business Logic Layer (BLL), die een methode aanroept in de juiste TableAdapter van Data Access Layer (DAL), die op zijn beurt een SELECT
query naar de Northwind-database verzendt.
Zoals u weet, heeft Visual Studio tijdens het maken van tableAdapters in de DAL in onze eerste zelfstudie automatisch methoden toegevoegd voor het invoegen, bijwerken en verwijderen van gegevens uit de onderliggende databasetabel. Bovendien hebben we bij het maken van een bedrijfslogicalaag methoden ontworpen in de BLL die in deze DAL-methoden voor gegevenswijziging zijn aangeroepen.
Naast de Select()
-methode heeft de ObjectDataSource ook de Insert()
, Update()
en Delete()
methoden. Net als bij de Select()
methode kunnen deze drie methoden worden toegewezen aan methoden in een onderliggend object. Wanneer de besturingselementen GridView, DetailsView en FormView zijn geconfigureerd voor het invoegen, bijwerken of verwijderen van gegevens, bieden ze een gebruikersinterface voor het wijzigen van de onderliggende gegevens. Deze gebruikersinterface roept de Insert()
, Update()
en Delete()
methoden van de ObjectDataSource aan, die vervolgens de bijbehorende methoden van het onderliggende object aanroepen (zie afbeelding 1).
Afbeelding 1: De objectDataSource's Insert()
en Update()
Delete()
methoden fungeren als proxy in de BLL (klik om de volledige afbeelding weer te geven)
In deze zelfstudie ziet u hoe u de methoden van ObjectDataSource Insert()
, Update()
en Delete()
kunt toewijzen aan methoden van klassen in de BLL, en hoe u de besturingselementen GridView, DetailsView en FormView configureert om de mogelijkheid te bieden gegevens te wijzigen.
Stap 1: de webpagina's voor invoegen, bijwerken en verwijderen van zelfstudies maken
Voordat we beginnen met het invoegen, bijwerken en verwijderen van gegevens, gaan we eerst de ASP.NET pagina's in ons websiteproject maken die we nodig hebben voor deze zelfstudie en de volgende. Begin met het toevoegen van een nieuwe map met de naam EditInsertDelete
. Voeg vervolgens de volgende ASP.NET pagina's toe aan die map en zorg ervoor dat u elke pagina koppelt aan de Site.master
basispagina:
Default.aspx
Basics.aspx
DataModificationEvents.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
Afbeelding 2: De ASP.NET pagina's voor de zelfstudies voor gegevens Modification-Related toevoegen
Net als in de andere mappen, zal Default.aspx
in de map EditInsertDelete
de zelfstudies in zijn sectie weergeven. Zoals u weet, biedt het SectionLevelTutorialListing.ascx
gebruikersbeheer deze functionaliteit. Voeg deze gebruikerscontrole toe aan Default.aspx
door deze vanuit Solution Explorer naar de ontwerpweergave van de pagina te slepen.
Afbeelding 3: Het gebruikersbesturingselement toevoegen SectionLevelTutorialListing.ascx
aan Default.aspx
(klik om de afbeelding op volledige grootte weer te geven)
Voeg tot slot de pagina's toe als vermeldingen aan het Web.sitemap
bestand. Voeg met name de volgende markeringen toe na de aangepaste opmaak <siteMapNode>
:
<siteMapNode title="Editing, Inserting, and Deleting" url="~/EditInsertDelete/Default.aspx" description="Samples of Reports that Provide Editing, Inserting, and Deleting Capabilities"> <siteMapNode url="~/EditInsertDelete/Basics.aspx" title="Basics" description="Examines the basics of data modification with the GridView, DetailsView, and FormView controls." /> <siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx" title="Data Modification Events" description="Explores the events raised by the ObjectDataSource pertinent to data modification." /> <siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx" title="Error Handling" description="Learn how to gracefully handle exceptions raised during the data modification workflow." /> <siteMapNode url="~/EditInsertDelete/UIValidation.aspx" title="Adding Data Entry Validation" description="Help prevent data entry errors by providing validation." /> <siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx" title="Customize the User Interface" description="Customize the editing and inserting user interfaces." /> <siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx" title="Optimistic Concurrency" description="Learn how to help prevent simultaneous users from overwritting one another s changes." /> <siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx" title="Confirm On Delete" description="Prompt a user for confirmation when deleting a record." /> <siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx" title="Limit Capabilities Based on User" description="Learn how to limit the data modification functionality based on the user role or permissions." /> </siteMapNode>
Neem na het bijwerken Web.sitemap
even de moeite om de tutorialswebsite via een browser te bekijken. Het menu aan de linkerkant bevat nu items voor bewerken, invoegen, en verwijderen van tutorials.
Afbeelding 4: De sitemap bevat nu vermeldingen voor bewerken, invoegen en verwijderen van handleidingen
Stap 2: Het ObjectDataSource-besturingselement toevoegen en configureren
Aangezien de GridView, DetailsView en FormView elk verschillen in de mogelijkheden en indeling van gegevenswijziging, gaan we elk afzonderlijk bekijken. In plaats van dat elk besturingselement zijn eigen ObjectDataSource gebruikt, laten we één ObjectDataSource creëren die door alle drie de voorbeelden van besturingselementen gedeeld kan worden.
Open de Basics.aspx
pagina, sleep een ObjectDataSource van de Werkset naar de Ontwerper en klik op de koppeling Gegevensbron configureren vanuit de smarttag. Omdat dit ProductsBLL
de enige BLL-klasse is die methoden biedt voor bewerken, invoegen en verwijderen, configureert u de ObjectDataSource voor het gebruik van deze klasse.
Afbeelding 5: De ObjectDataSource configureren om de ProductsBLL
klasse te gebruiken (klik om de afbeelding op volledige grootte weer te geven)
In het volgende scherm kunnen we opgeven welke methoden van de ProductsBLL
klasse zijn toegewezen aan de objectgegevensbronSelect()
, Insert()
Update()
en Delete()
door het juiste tabblad te selecteren en de methode te kiezen in de vervolgkeuzelijst. Afbeelding 6, die nu bekend moet lijken, brengt de methode van Select()
ObjectDataSource in verband met de methode van de ProductsBLL
klasse's GetProducts()
methode. De Insert()
, Update()
en Delete()
methoden kunnen worden geconfigureerd door het juiste tabblad in de lijst bovenaan te selecteren.
Afbeelding 6: Laat de ObjectDataSource Alle producten retourneren (klik om de volledige afbeelding weer te geven)
In afbeeldingen 7, 8 en 9 worden de tabbladen UPDATE, INSERT en DELETE van ObjectDataSource weergegeven. Configureer deze tabbladen zodat de Insert()
, Update()
en Delete()
methoden respectievelijk de ProductsBLL
klassen UpdateProduct
en AddProduct
DeleteProduct
methoden aanroepen.
Afbeelding 7: Wijs de methode van Update()
ObjectDataSource toe aan de methode van ProductBLL
de UpdateProduct
klasse (klik om de afbeelding op volledige grootte weer te geven)
Afbeelding 8: Wijs de methode van Insert()
ObjectDataSource toe aan de methode Toevoegen ProductBLL
van de Product
klasse (klik om de volledige afbeelding weer te geven)
Afbeelding 9: Wijs de methode van Delete()
ObjectDataSource toe aan de methode van ProductBLL
de DeleteProduct
klasse (klik om de afbeelding op volledige grootte weer te geven)
Mogelijk hebt u gemerkt dat in de vervolgkeuzelijsten op de tabbladen UPDATE, INSERT en DELETE al deze methoden zijn geselecteerd. Dit is te danken aan ons gebruik van de DataObjectMethodAttribute
die de methoden van ProductsBLL
verfraait. De methode DeleteProduct heeft bijvoorbeeld de volgende handtekening:
<System.ComponentModel.DataObjectMethodAttribute _ (System.ComponentModel.DataObjectMethodType.Delete, True)> _ Public Function DeleteProduct(ByVal productID As Integer) As Boolean End Function
Het DataObjectMethodAttribute
kenmerk geeft het doel aan van elke methode, ongeacht of het gaat om het selecteren, invoegen, bijwerken of verwijderen en of het de standaardwaarde is. Als u deze kenmerken weglaat bij het maken van uw BLL-klassen, moet u handmatig de methoden selecteren op de tabbladen UPDATE, INSERT en DELETE.
Nadat u ervoor hebt gezorgd dat de juiste ProductsBLL
methoden zijn toegewezen aan de objectdatabron Insert()
Update()
en Delete()
methoden, klikt u op Voltooien om de wizard te voltooien.
De markeringen van ObjectDataSource onderzoeken
Nadat u de ObjectDataSource hebt geconfigureerd via de wizard, gaat u naar de bronweergave om de gegenereerde declaratieve markeringen te onderzoeken. De <asp:ObjectDataSource>
tag specificeert het onderliggende object en de methoden die moeten worden aangeroepen. Daarnaast zijn DeleteParameters
, UpdateParameters
en InsertParameters
die worden toegewezen aan de invoerparameters voor de klasse ProductsBLL
en de methoden AddProduct
, UpdateProduct
en DeleteProduct
.
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="DeleteProduct" InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts" TypeName="ProductsBLL" UpdateMethod="UpdateProduct"> <DeleteParameters> <asp:Parameter Name="productID" Type="Int32" /> </DeleteParameters> <UpdateParameters> <asp:Parameter Name="productName" Type="String" /> <asp:Parameter Name="supplierID" Type="Int32" /> <asp:Parameter Name="categoryID" Type="Int32" /> <asp:Parameter Name="quantityPerUnit" Type="String" /> <asp:Parameter Name="unitPrice" Type="Decimal" /> <asp:Parameter Name="unitsInStock" Type="Int16" /> <asp:Parameter Name="unitsOnOrder" Type="Int16" /> <asp:Parameter Name="reorderLevel" Type="Int16" /> <asp:Parameter Name="discontinued" Type="Boolean" /> <asp:Parameter Name="productID" Type="Int32" /> </UpdateParameters> <InsertParameters> <asp:Parameter Name="productName" Type="String" /> <asp:Parameter Name="supplierID" Type="Int32" /> <asp:Parameter Name="categoryID" Type="Int32" /> <asp:Parameter Name="quantityPerUnit" Type="String" /> <asp:Parameter Name="unitPrice" Type="Decimal" /> <asp:Parameter Name="unitsInStock" Type="Int16" /> <asp:Parameter Name="unitsOnOrder" Type="Int16" /> <asp:Parameter Name="reorderLevel" Type="Int16" /> <asp:Parameter Name="discontinued" Type="Boolean" /> </InsertParameters> </asp:ObjectDataSource>
ObjectDataSource bevat een parameter voor elk van de invoerparameters voor de bijbehorende methoden, net zoals een lijst SelectParameter
met s aanwezig is wanneer de ObjectDataSource is geconfigureerd voor het aanroepen van een select-methode die een invoerparameter verwacht (zoals GetProductsByCategoryID(categoryID)
). Zoals we binnenkort zullen zien, worden waarden voor deze DeleteParameters
, UpdateParameters
, en InsertParameters
automatisch ingesteld door de GridView, DetailsView en FormView voordat de methode Insert()
, Update()
, of Delete()
van de ObjectDataSource wordt aangeroepen. Deze waarden kunnen ook programmatisch worden ingesteld, zoals we in een toekomstige zelfstudie zullen bespreken.
Een neveneffect van het gebruik van de wizard om te configureren voor ObjectDataSource is dat Visual Studio de eigenschap OldValuesParameterFormatString instelt oporiginal_{0}
. Deze eigenschapswaarde wordt gebruikt om de oorspronkelijke waarden op te nemen van de gegevens die worden bewerkt en is handig in twee scenario's:
- Als gebruikers bij het bewerken van een record de primaire-sleutelwaarde kunnen wijzigen. In dit geval moeten zowel de nieuwe primaire sleutelwaarde als de oorspronkelijke primaire-sleutelwaarde worden opgegeven, zodat de record met de oorspronkelijke primaire-sleutelwaarde kan worden gevonden en de waarde dienovereenkomstig moet worden bijgewerkt.
- Wanneer u optimistische gelijktijdigheid gebruikt. Optimistische gelijktijdigheid is een techniek om ervoor te zorgen dat twee gelijktijdige gebruikers elkaars wijzigingen niet overschrijven en het onderwerp is voor een toekomstige zelfstudie.
De OldValuesParameterFormatString
eigenschap geeft de naam aan van de invoerparameters in de update- en verwijdermethoden van het onderliggende object voor de oorspronkelijke waarden. We bespreken deze eigenschap en het doel ervan in meer detail wanneer we optimistische gelijktijdigheid onderzoeken. Ik breng het nu echter aan, omdat onze methoden van BLL de oorspronkelijke waarden niet verwachten en daarom is het belangrijk dat we deze eigenschap verwijderen. Als de OldValuesParameterFormatString
eigenschap is ingesteld op iets anders dan de standaardwaarde ({0}
), wordt een fout veroorzaakt wanneer een webbesturingselement voor gegevens probeert de methoden Update()
of Delete()
van ObjectDataSource aan te roepen, omdat de ObjectDataSource zowel de opgegeven waarde UpdateParameters
als de oorspronkelijke waardeparameters DeleteParameters
probeert door te geven.
Als dit op dit moment niet erg duidelijk is, maak je geen zorgen, we zullen deze eigenschap en het gebruik ervan in een toekomstige tutorial onderzoeken. Voorlopig moet u deze eigenschapsdeclaratie helemaal uit de declaratieve syntaxis verwijderen of de waarde instellen op de standaardwaarde ({0}).
Opmerking
Als u de eigenschapswaarde uit het OldValuesParameterFormatString
venster Eigenschappen in de ontwerpweergave wist, bestaat de eigenschap nog steeds in de declaratieve syntaxis, maar wordt deze ingesteld op een lege tekenreeks. Dit leidt helaas nog steeds tot hetzelfde probleem dat hierboven is besproken. Verwijder daarom de eigenschap helemaal uit de declaratieve syntaxis of stel in het venster Eigenschappen de waarde in op de standaardwaarde {0}
.
Stap 3: Een gegevenswebbeheer toevoegen en configureren voor gegevenswijziging
Zodra de ObjectDataSource is toegevoegd aan de pagina en is geconfigureerd, zijn we klaar om webbesturingselementen voor gegevens toe te voegen aan de pagina om de gegevens weer te geven en een middel te bieden voor de eindgebruiker om deze te wijzigen. We kijken afzonderlijk naar GridView, DetailsView en FormView, omdat deze besturingselementen voor gegevensweb verschillen in de mogelijkheden en configuratie van gegevenswijziging.
Zoals we in de rest van dit artikel zullen zien, is het toevoegen van zeer eenvoudige bewerkingen, invoegen en verwijderen van ondersteuning via de besturingselementen GridView, DetailsView en FormView heel eenvoudig als het controleren van een aantal selectievakjes. Er zijn veel subtiliteiten en randgevallen in de echte wereld die ervoor zorgen dat dergelijke functionaliteit complexer is dan eenvoudigweg aanwijzen en klikken. Deze handleiding richt zich echter uitsluitend op het demonstreren van eenvoudige mogelijkheden voor het wijzigen van gegevens. Toekomstige handleidingen zullen zorgen behandelen die ongetwijfeld zullen optreden in een praktijksituatie.
Gegevens verwijderen uit de GridView
Begin door een GridView vanuit de Toolbox naar de Ontwerper te slepen. Bind vervolgens de ObjectDataSource aan de GridView door deze te selecteren in de vervolgkeuzelijst in de smart tag van GridView. Op dit moment is de declaratieve markering van GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <Columns> <asp:BoundField DataField="ProductID" HeaderText="ProductID" InsertVisible="False" ReadOnly="True" SortExpression="ProductID" /> <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" /> <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" /> <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" SortExpression="CategoryID" /> <asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit" SortExpression="QuantityPerUnit" /> <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" /> <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" SortExpression="UnitsInStock" /> <asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" /> <asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel" SortExpression="ReorderLevel" /> <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued" /> <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" ReadOnly="True" SortExpression="CategoryName" /> <asp:BoundField DataField="SupplierName" HeaderText="SupplierName" ReadOnly="True" SortExpression="SupplierName" /> </Columns> </asp:GridView>
Het binden van GridView aan de ObjectDataSource via de slimme tag heeft twee voordelen:
- BoundFields en CheckBoxFields worden automatisch gemaakt voor elk van de velden die worden geretourneerd door de ObjectDataSource. Bovendien worden de eigenschappen van BoundField en CheckBoxField ingesteld op basis van de metagegevens van het onderliggende veld. De velden
ProductID
,CategoryName
enSupplierName
zijn bijvoorbeeld gemarkeerd als alleen-lezen in deProductsDataTable
, en daarom mogen ze niet worden gewijzigd tijdens het bewerken. Om dit mogelijk te maken, zijn deze ReadOnly-eigenschappen van BoundFields ingesteld opTrue
. - De eigenschap DataKeyNames wordt toegewezen aan de primaire-sleutelvelden van het onderliggende object. Dit is essentieel bij het gebruik van GridView voor het bewerken of verwijderen van gegevens, omdat deze eigenschap het veld (of de set velden) aangeeft die uniek zijn voor elke record. Raadpleeg de tutorial
DataKeyNames
voor meer informatie over de eigenschap .
Hoewel GridView kan worden gebonden aan de ObjectDataSource via het venster Eigenschappen of declaratieve syntaxis, moet u hiervoor handmatig de juiste BoundField en DataKeyNames
markeringen toevoegen.
Het GridView-besturingselement biedt ingebouwde ondersteuning voor bewerken en verwijderen op rijniveau. Als u een GridView configureert ter ondersteuning van verwijderen, wordt een kolom met knoppen Verwijderen toegevoegd. Wanneer de eindgebruiker op de knop Verwijderen voor een bepaalde rij klikt, wordt een postback gevolgd en voert GridView de volgende stappen uit:
- De waarde(s) van
DeleteParameters
ObjectDataSource worden toegewezen - De methode van
Delete()
ObjectDataSource wordt aangeroepen, waarbij de opgegeven record wordt verwijderd - GridView wordt opnieuw gekoppeld aan de ObjectDataSource door zijn
Select()
-methode aan te roepen.
De waarden die aan de DeleteParameters
zijn toegewezen, zijn de waarden van de DataKeyNames
velden voor de rij waarvoor op Verwijderen is geklikt. Daarom is het essentieel dat de eigenschap DataKeyNames
van een GridView correct is ingesteld. Als het ontbreekt, krijgt het DeleteParameters
een waarde van Nothing
toegewezen in stap 1, wat op zijn beurt niet resulteert in verwijderde records in stap 2.
Opmerking
De DataKeys
verzameling wordt opgeslagen in de besturingsstatus van GridView, wat betekent dat de DataKeys
waarden worden onthouden in de postback, zelfs als de weergavestatus van GridView is uitgeschakeld. Het is echter erg belangrijk dat de weergavestatus ingeschakeld blijft voor GridViews die ondersteuning bieden voor bewerken of verwijderen (het standaardgedrag). Als u de eigenschap EnableViewState
GridView false
instelt op, werkt het bewerkings- en verwijdergedrag prima voor één gebruiker, maar als er gelijktijdige gebruikers gegevens verwijderen, bestaat de mogelijkheid dat deze gelijktijdige gebruikers per ongeluk records verwijderen of bewerken die ze niet van plan waren.
Dezelfde waarschuwing geldt ook voor DetailsViews en FormViews.
Als u mogelijkheden voor verwijderen aan een GridView wilt toevoegen, gaat u naar de infotag en schakelt u het selectievakje Verwijderen inschakelen in.
Afbeelding 10: Selecteer het selectievakje voor Verwijderen inschakelen
Als u het selectievakje Verwijderen aanvinkt vanuit de smarttag, wordt er een CommandField aan de GridView toegevoegd. CommandField geeft een kolom weer in GridView met knoppen voor het uitvoeren van een of meer van de volgende taken: het selecteren van een record, het bewerken van een record en het verwijderen van een record. We hebben het CommandField eerder aan het werk gezien bij het selecteren van records in de Master/Detail Using a Selectable Master GridView with a Details DetailView tutorial.
Het CommandField bevat een aantal ShowXButton
eigenschappen die aangeven welke reeks knoppen wordt weergegeven in het CommandField. Door het selectievakje Verwijderen inschakelen aan te vinken, is er een CommandField toegevoegd aan de Kolommen-verzameling van de GridView, waarbij de eigenschap ShowDeleteButton
True
is.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <Columns> <asp:CommandField ShowDeleteButton="True" /> ... BoundFields removed for brevity ... </Columns> </asp:GridView>
Op dit moment, geloof het of niet, we zijn klaar met het toevoegen van verwijderingsondersteuning aan de GridView! Zoals in afbeelding 11 wordt weergegeven, is bij het bezoeken van deze pagina via een browser een kolom met knoppen Verwijderen aanwezig.
Afbeelding 11: Met CommandField wordt een kolom met verwijderknoppen toegevoegd (klik om de afbeelding op volledige grootte weer te geven)
Als u deze zelfstudie vanaf nul helemaal zelf hebt opgebouwd, zal bij het testen van deze pagina het klikken op de knop Verwijderen een uitzondering genereren. Lees verder om te leren waarom deze uitzonderingen zijn gegenereerd en hoe u deze kunt oplossen.
Opmerking
Als u de download bij deze zelfstudie gebruikt, zijn deze problemen al opgelost. Ik moedig u echter aan de onderstaande details door te lezen om problemen te identificeren die zich kunnen voordoen en geschikte tijdelijke oplossingen.
Als u bij het verwijderen van een product een uitzondering krijgt met een bericht dat vergelijkbaar is met ObjectDataSource 'ObjectDataSource1' kon geen niet-generieke methode 'DeleteProduct' vinden met parameters: productID, original_ProductID, dan heeft u waarschijnlijk de OldValuesParameterFormatString
eigenschap uit de ObjectDataSource te verwijderen vergeten. Met de opgegeven eigenschap OldValuesParameterFormatString
, probeert ObjectDataSource zowel de invoerparameters productID
en original_ProductID
door te geven aan de DeleteProduct
methode.
DeleteProduct
accepteert echter slechts één invoerparameter, vandaar de uitzondering. Als u de OldValuesParameterFormatString
eigenschap verwijdert (of instelt op {0}
) wordt de ObjectDataSource geïnstrueerd om de oorspronkelijke invoerparameter niet door te geven.
Afbeelding 12: Zorg ervoor dat de OldValuesParameterFormatString
eigenschap is gewist (klik om de afbeelding op volledige grootte weer te geven)
Zelfs als u de OldValuesParameterFormatString
eigenschap hebt verwijderd, krijgt u nog steeds een uitzondering bij het verwijderen van een product met het bericht: 'De INSTRUCTIE DELETE is conflicterend met de VERWIJZINGsbeperking 'FK_Order_Details_Products'. De Northwind-database bevat een beperking voor refererende sleutels tussen de Order Details
en Products
tabel, wat betekent dat een product niet uit het systeem kan worden verwijderd als er een of meer records voor in de Order Details
tabel staan. Omdat elk product in de Northwind-database ten minste één record Order Details
bevat, kunnen we geen producten verwijderen totdat we eerst de bijbehorende ordergegevensrecords van het product verwijderen.
Afbeelding 13: Een beperking voor refererende sleutels verbiedt het verwijderen van producten (klik om de afbeelding op volledige grootte weer te geven)
Voor onze zelfstudie gaan we alleen alle records uit de Order Details
tabel verwijderen. In een echte toepassing zouden we het volgende moeten doen:
- Een ander scherm hebben om informatie over ordergegevens te beheren
-
DeleteProduct
De methode uitbreiden om logica op te nemen om de ordergegevens van het opgegeven product te verwijderen - Wijzig de SQL-query die door de TableAdapter wordt gebruikt om het verwijderen van de ordergegevens van het opgegeven product op te nemen
We verwijderen alle records uit de Order Details
tabel om de beperking van de buitenlandse sleutel te omzeilen. Ga naar Server Explorer in Visual Studio, klik met de rechtermuisknop op het NORTHWND.MDF
knooppunt en kies Nieuwe query. Voer vervolgens in het queryvenster de volgende SQL-instructie uit: DELETE FROM [Order Details]
Afbeelding 14: Alle records uit de Order Details
tabel verwijderen (klik om de volledige afbeelding weer te geven)
Nadat u de Order Details
tabel hebt gewist waarop u op de knop Verwijderen klikt, wordt het product zonder fouten verwijderd. Als klikken op de knop Verwijderen het product niet verwijdert, controleer dan of de eigenschap van de GridView DataKeyNames
is ingesteld op het primaire-sleutelveld (ProductID
).
Opmerking
Wanneer u op de knop Verwijderen klikt, wordt een postback uitgevoerd en wordt de record verwijderd. Dit kan gevaarlijk zijn omdat het gemakkelijk is om per ongeluk op de verkeerde rij te klikken op de knop Verwijderen. In een toekomstige zelfstudie zien we hoe u een bevestiging aan de clientzijde toevoegt bij het verwijderen van een record.
Gegevens bewerken met GridView
Naast het verwijderen biedt het besturingselement GridView ook ingebouwde ondersteuning voor bewerking op rijniveau. Als u een GridView configureert ter ondersteuning van bewerken, wordt een kolom met knoppen Bewerken toegevoegd. Als u vanuit het perspectief van de eindgebruiker op de knop Bewerken van een rij klikt, wordt de rij bewerkbaar, worden de cellen omgezet in tekstvakken die de bestaande waarden bevatten en vervangt u de knop Bewerken door de knoppen Bijwerken en Annuleren. Nadat de gewenste wijzigingen zijn aangebracht, kan de eindgebruiker op de knop Bijwerken klikken om de wijzigingen door te voeren of op de knop Annuleren om ze te negeren. Na het klikken op Bijwerken of Annuleren keert de GridView in beide gevallen terug naar zijn oorspronkelijke staat.
Vanuit ons perspectief als paginaontwikkelaar leidt het klikken op de knop Bewerken voor een bepaalde rij door de eindgebruiker tot een postback, waarna de GridView de volgende stappen uitvoert:
- De eigenschap van GridView
EditItemIndex
is toegewezen aan de index van de rij waarvan op de knop Bewerken is geklikt - GridView wordt opnieuw gekoppeld aan de ObjectDataSource door zijn
Select()
-methode aan te roepen. - De rijindex die overeenkomt met de
EditItemIndex
rij wordt weergegeven in de 'bewerkingsmodus'. In deze modus wordt de knop Bewerken vervangen door de knoppen Bijwerken en Annuleren en BoundFields waarvanReadOnly
de eigenschappen Onwaar (de standaardinstelling) zijn, worden weergegeven als webbesturingselementen voor tekstvakken waarvanText
de eigenschappen zijn toegewezen aan de waarden van de gegevensvelden.
Op dit moment wordt de markering geretourneerd naar de browser, zodat de eindgebruiker wijzigingen kan aanbrengen in de gegevens van de rij. Wanneer de gebruiker op de knop Bijwerken klikt, wordt er een terugpost uitgevoerd en voert de GridView de volgende stappen uit:
- De waarde(s) van
UpdateParameters
ObjectDataSource worden toegewezen aan de waarden die de eindgebruiker heeft ingevoerd in de bewerkingsinterface van GridView - De methode van
Update()
ObjectDataSource wordt aangeroepen, waarbij de opgegeven record wordt bijgewerkt - GridView wordt opnieuw gekoppeld aan de ObjectDataSource door zijn
Select()
-methode aan te roepen.
De primaire sleutelwaarden die aan de UpdateParameters
in stap 1 zijn toegewezen, zijn afkomstig van de waarden die zijn opgegeven in de DataKeyNames
eigenschap, terwijl de niet-primaire-sleutelwaarden afkomstig zijn van de tekst in de besturingselementen voor het tekstvakweb voor de bewerkte rij. Net als bij het verwijderen is het essentieel dat de eigenschap van DataKeyNames
GridView correct wordt ingesteld. Als deze ontbreekt, krijgt de waarde van de UpdateParameters
primaire sleutel de waarde van Nothing
in stap 1, wat op zijn beurt niet resulteert in bijgewerkte records in stap 2.
Bewerkingsfunctionaliteit kan worden geactiveerd door het selectievakje 'Bewerken inschakelen' aan te vinken in de smart-tag van GridView.
Afbeelding 15: Vink het selectievakje voor bewerken aan
Door het selectievakje Bewerken inschakelen, wordt een CommandField (indien nodig) toegevoegd en de eigenschap ShowEditButton
ingesteld op True
. Zoals we eerder hebben gezien, bevat het CommandField een aantal ShowXButton
eigenschappen die aangeven welke reeks knoppen worden weergegeven in het CommandField. Als u het selectievakje Bewerken inschakelen inschakelt, wordt de ShowEditButton
eigenschap toegevoegd aan het bestaande CommandField:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <Columns> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" /> ... BoundFields removed for brevity ... </Columns> </asp:GridView>
Dat is alles wat er is om elementaire bewerkingsondersteuning toe te voegen. Zoals in Figuur 16 wordt weergegeven, is de bewerkingsinterface nogal primitief. Elk BoundField waarvan de eigenschap ReadOnly
is ingesteld op False
(de standaardinstelling), wordt weergegeven als een tekstvak. Dit omvat velden zoals CategoryID
en SupplierID
, die sleutels zijn voor andere tabellen.
Afbeelding 16: Als u op de bewerkknop van Chai klikt, wordt de rij weergegeven in de bewerkingsmodus (Klik om de afbeelding in volledige grootte te bekijken)
Naast het vragen van gebruikers om buitenlandse sleutelwaarden rechtstreeks te bewerken, schiet de bewerkingsinterface tekort op de volgende punten:
- Als de gebruiker een
CategoryID
ofSupplierID
invoert die niet in de database bestaat, zal een foreign key beperking worden geschonden, waardoor een uitzondering optreedt. - De bewerkingsinterface bevat geen validatie. Als u geen vereiste waarde opgeeft (zoals
ProductName
) of een tekenreekswaarde invoert waarbij een numerieke waarde wordt verwacht (zoals 'Te veel!' invoeren in hetUnitPrice
tekstvak), wordt er een uitzondering gegenereerd. In een toekomstige handleiding wordt onderzocht hoe u validatie-elementen toevoegt aan de gebruikersinterface voor bewerken. - Op dit moment moeten alle productvelden die niet readonly zijn, worden opgenomen in de GridView. Als we een veld uit GridView zouden verwijderen, bijvoorbeeld
UnitPrice
wanneer we de gegevens bijwerken, zou de GridView deUnitPrice
UpdateParameters
waarde niet instellen, waardoor de databaserecordsUnitPrice
zouden worden gewijzigd in eenNULL
waarde. Als een vereist veld, zoalsProductName
, wordt verwijderd uit de GridView, mislukt de update met dezelfde uitzondering "Kolom 'ProductName' staat geen nullen toe" die hierboven wordt vermeld. - De opmaak van de bewerkingsinterface laat veel te wensen over. De
UnitPrice
wordt weergegeven met vier decimalen. Idealiter bevatten deCategoryID
enSupplierID
waarden vervolgkeuzelijsten waarin de categorieën en leveranciers in het systeem worden vermeld.
Dit zijn allemaal tekortkomingen waarmee we nu moeten leven, maar worden in toekomstige zelfstudies behandeld.
Gegevens invoegen, bewerken en verwijderen met de DetailsView
Zoals we in eerdere tutoriëls hebben gezien, wordt in het besturingselement DetailsView één record tegelijk weergegeven en kan, net als de GridView, het huidige weergegeven record worden bewerkt en verwijderd. Zowel de ervaring van de eindgebruiker met het bewerken en verwijderen van items uit een DetailsView als de werkstroom aan de ASP.NET kant is identiek aan die van de GridView. Waar de DetailsView verschilt van de GridView, is dat het ook ingebouwde ondersteuning biedt voor invoegen.
Als u de mogelijkheden voor het wijzigen van gegevens van GridView wilt demonstreren, voegt u eerst een DetailsView toe aan de pagina boven de Basics.aspx
bestaande GridView en verbindt u deze met de bestaande ObjectDataSource via de infotag van de DetailsView. Schakel vervolgens de eigenschappen Height
en Width
van de DetailsView uit en vink de optie Paginering inschakelen aan via de smarttag. Als u ondersteuning voor bewerken, invoegen en verwijderen wilt inschakelen, schakelt u de selectievakjes Bewerken inschakelen, Invoegen inschakelen en Verwijderen inschakelen in de infotag in.
Afbeelding 17: DetailsView configureren ter ondersteuning van bewerken, invoegen en verwijderen
Net als bij de GridView voegt het toevoegen van bewerk-, invoeg- of verwijderondersteuning een CommandField toe aan de DetailsView, zoals de volgende declaratieve syntaxis toont.
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <Fields> <asp:BoundField DataField="ProductID" HeaderText="ProductID" InsertVisible="False" ReadOnly="True" SortExpression="ProductID" /> <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" /> <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" /> <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" SortExpression="CategoryID" /> <asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit" SortExpression="QuantityPerUnit" /> <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" /> <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" SortExpression="UnitsInStock" /> <asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" /> <asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel" SortExpression="ReorderLevel" /> <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued" /> <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" ReadOnly="True" SortExpression="CategoryName" /> <asp:BoundField DataField="SupplierName" HeaderText="SupplierName" ReadOnly="True" SortExpression="SupplierName" /> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowInsertButton="True" /> </Fields> </asp:DetailsView>
Houd er rekening mee dat voor DetailsView het CommandField standaard aan het einde van de collectie kolommen verschijnt. Omdat de velden van DetailsView als rijen worden weergegeven, wordt het CommandField weergegeven als een rij met de knoppen Invoegen, Bewerken en Verwijderen onder aan de DetailsView.
Afbeelding 18: De DetailsView configureren ter ondersteuning van bewerken, invoegen en verwijderen (klik om de volledige afbeelding weer te geven)
Als u op de knop Verwijderen klikt, wordt dezelfde reeks gebeurtenissen gestart als bij gridview: een terugpost; gevolgd door de DetailsView waarin de ObjectDataSource's DeleteParameters
worden ingevuld op basis van de DataKeyNames
waarden; en voltooid met een aanroep van de methode objectDataSource Delete()
, waarmee het product daadwerkelijk uit de database wordt verwijderd. Bewerken in de DetailsView werkt ook op een manier die identiek is aan die van de GridView.
Voor het invoegen krijgt de eindgebruiker een knop Nieuw te zien die, wanneer erop wordt geklikt, de DetailsView in de 'invoegmodus' weergeeft. Met de 'invoegmodus' wordt de knop Nieuw vervangen door de knoppen Invoegen en Annuleren en worden alleen de Afhankelijkvelden waarvan InsertVisible
de eigenschap is ingesteld True
op (de standaardinstelling) weergegeven. Voor gegevensvelden die zijn geïdentificeerd als auto-increment velden, zoals ProductID
, wordt de eigenschap InsertVisible op False
ingesteld wanneer de DetailsView via de slimme tag aan de gegevensbron wordt gekoppeld.
Wanneer u een gegevensbron via de infotag aan een DetailsView bindt, stelt Visual Studio de InsertVisible
eigenschap False
alleen in voor velden die automatisch worden verhoogd. Alleen-lezenvelden, zoals CategoryName
en SupplierName
, worden weergegeven in de gebruikersinterface voor invoegen, tenzij hun InsertVisible
-eigenschap expliciet is ingesteld op False
. Neem even de tijd om de eigenschappen van deze twee velden InsertVisible
in te stellen op False
, ofwel via de declaratieve syntaxis van de DetailsView of via de koppeling Velden bewerken in de infolabel. In afbeelding 19 ziet u hoe de InsertVisible
eigenschappen worden ingesteld op False
door op de koppeling Velden bewerken te klikken.
Afbeelding 19: Northwind Traders biedt nu Acme Tea (klik hier om de afbeelding volledig weer te geven)
Nadat u de InsertVisible
eigenschappen hebt ingesteld, bekijkt u de Basics.aspx
pagina in een browser en klikt u op de knop Nieuw. Afbeelding 20 toont de DetailsView bij het toevoegen van een nieuwe drank, Acme Tea, aan onze productlijn.
Afbeelding 20: Northwind Traders biedt nu Acme Tea (klik om de afbeelding volledig weer te geven)
Nadat u de details voor Acme Tea hebt ingevoerd en op de knop Invoegen hebt geklikt, wordt een postback weergegeven en wordt de nieuwe record toegevoegd aan de Products
databasetabel. Aangezien in deze DetailsView de producten worden vermeld in de volgorde waarin ze in de databasetabel staan, moeten we naar het laatste product gaan om het nieuwe product te kunnen zien.
Afbeelding 21: Details voor Acme Tea (klik om de afbeelding op volledige grootte weer te geven)
Opmerking
De eigenschap CurrentMode van DetailsView geeft de interface aan die wordt weergegeven en kan een van de volgende waarden zijn: Edit
, Insert
of ReadOnly
. De eigenschap DefaultMode geeft de modus aan waarnaar de DetailsView terugkeert nadat een bewerking of invoegbewerking is voltooid en is handig voor het weergeven van een DetailsView die permanent in de bewerkings- of invoegmodus staat.
De aanwijs- en klikfuncties van de DetailsView hebben dezelfde beperkingen als die van de GridView: de gebruiker moet bestaande CategoryID
en SupplierID
waarden invoeren via een tekstvak; de interface mist validatielogica; alle productvelden die geen NULL
waarden toestaan of waarvoor geen standaardwaarde is opgegeven op databaseniveau, moeten worden opgenomen in de invoeginterface, enzovoort.
De technieken die we gaan onderzoeken voor het uitbreiden en verbeteren van de bewerkingsinterface van GridView in toekomstige artikelen, kunnen ook worden toegepast op de bewerkings- en invoeginterfaces van het DetailView-besturingselement.
De FormView gebruiken voor een flexibelere gebruikersinterface voor het wijzigen van gegevens
De FormView biedt ingebouwde ondersteuning voor het invoegen, bewerken en verwijderen van gegevens, maar omdat er sjablonen worden gebruikt in plaats van velden, is er geen plaats om de BoundFields of het CommandField toe te voegen dat wordt gebruikt door de besturingselementen GridView en DetailsView om de interface voor gegevenswijziging te bieden. In plaats daarvan moeten de webbesturingselementen voor het verzamelen van gebruikersinvoer bij het toevoegen van een nieuw item of het bewerken van een bestaand item samen met de knoppen Nieuw, Bewerken, Verwijderen, Invoegen, Bijwerken en Annuleren handmatig worden toegevoegd aan de juiste sjablonen. Gelukkig maakt Visual Studio automatisch de benodigde interface wanneer de FormView wordt gekoppeld aan een gegevensbron via de vervolgkeuzelijst in de smart tag.
Als u deze technieken wilt illustreren, voegt u eerst een FormView toe aan de Basics.aspx
pagina en verbindt u deze vanuit de smarttag van FormView aan de ObjectDataSource die al is gemaakt. Hiermee genereert u een EditItemTemplate
, InsertItemTemplate
, en ItemTemplate
voor FormView met tekstvak webbesturingselementen voor het verzamelen van de invoer van de gebruiker en knopwebbesturingselementen voor de knoppen Nieuw, Bewerken, Verwijderen, Invoegen, Bijwerken en Annuleren. Daarnaast wordt de eigenschap van FormView DataKeyNames
ingesteld op het primaire-sleutelveld (ProductID
) van het object dat wordt geretourneerd door de ObjectDataSource. Schakel ten slotte de optie 'Paging inschakelen' in de smarttag van de FormView in.
Hieronder ziet u de declaratieve markeringen voor de FormView's ItemTemplate
nadat de FormView is gebonden aan de ObjectDataSource. Standaard is elk niet-Booleaanse waardeproductveld gebonden aan de Text
eigenschap van een labelwebbesturingselement, terwijl elk Booleaanse waardeveld (Discontinued
) is gebonden aan de Checked
eigenschap van een uitgeschakeld webbesturingselement Selectievakje. Om ervoor te zorgen dat de knoppen Nieuw, Bewerken en Verwijderen bepaalde FormView-werking activeren wanneer erop wordt geklikt, is het noodzakelijk dat hun CommandName
waarden worden ingesteld New
op respectievelijk , Edit
en Delete
.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <EditItemTemplate> ... </EditItemTemplate> <InsertItemTemplate> ... </InsertItemTemplate> <ItemTemplate> ProductID: <asp:Label ID="ProductIDLabel" runat="server" Text='<%# Eval("ProductID") %>'></asp:Label><br /> ProductName: <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Bind("ProductName") %>'> </asp:Label><br /> SupplierID: <asp:Label ID="SupplierIDLabel" runat="server" Text='<%# Bind("SupplierID") %>'> </asp:Label><br /> CategoryID: <asp:Label ID="CategoryIDLabel" runat="server" Text='<%# Bind("CategoryID") %>'> </asp:Label><br /> QuantityPerUnit: <asp:Label ID="QuantityPerUnitLabel" runat="server" Text='<%# Bind("QuantityPerUnit") %>'> </asp:Label><br /> UnitPrice: <asp:Label ID="UnitPriceLabel" runat="server" Text='<%# Bind("UnitPrice") %>'></asp:Label><br /> UnitsInStock: <asp:Label ID="UnitsInStockLabel" runat="server" Text='<%# Bind("UnitsInStock") %>'> </asp:Label><br /> UnitsOnOrder: <asp:Label ID="UnitsOnOrderLabel" runat="server" Text='<%# Bind("UnitsOnOrder") %>'> </asp:Label><br /> ReorderLevel: <asp:Label ID="ReorderLevelLabel" runat="server" Text='<%# Bind("ReorderLevel") %>'> </asp:Label><br /> Discontinued: <asp:CheckBox ID="DiscontinuedCheckBox" runat="server" Checked='<%# Bind("Discontinued") %>' Enabled="false" /><br /> CategoryName: <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Bind("CategoryName") %>'> </asp:Label><br /> SupplierName: <asp:Label ID="SupplierNameLabel" runat="server" Text='<%# Bind("SupplierName") %>'> </asp:Label><br /> <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"> </asp:LinkButton> <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"> </asp:LinkButton> <asp:LinkButton ID="NewButton" runat="server" CausesValidation="False" CommandName="New" Text="New"> </asp:LinkButton> </ItemTemplate> </asp:FormView>
Afbeelding 22 toont de FormView's ItemTemplate
wanneer deze worden bekeken via een browser. Elk productveld wordt weergegeven met de knoppen Nieuw, Bewerken en Verwijderen onderaan.
Afbeelding 22: Defaut FormView ItemTemplate
bevat elk productveld, samen met nieuwe, bewerkings- en verwijderknoppen (klik om de volledige afbeelding weer te geven)
Net als bij GridView en DetailsView, wanneer u klikt op de knop Verwijderen of op een knop, LinkButton of ImageButton waarvan de CommandName
-eigenschap is ingesteld op Verwijderen, wordt een postback uitgevoerd, wordt de ObjectDataSource gevuld op basis van de FormView-waarde DeleteParameters
, en wordt de methode DataKeyNames
van de ObjectDataSource aangeroepen.
Wanneer op de knop Bewerken wordt geklikt, volgt er een postback en worden de gegevens teruggebonden aan de EditItemTemplate
, die verantwoordelijk is voor het weergeven van de bewerkingsinterface. Deze interface bevat de webbesturingselementen voor het bewerken van gegevens, samen met de knoppen Bijwerken en Annuleren. De standaardwaarde EditItemTemplate
die door Visual Studio wordt gegenereerd, bevat een label voor velden die automatisch worden verhoogd (ProductID
), een tekstvak voor elk veld met een niet-Booleaanse waarde en een selectievakje voor elk booleaanse waardeveld. Dit gedrag is vergelijkbaar met de automatisch gegenereerde BoundFields in de besturingselementen GridView en DetailsView.
Opmerking
Een klein probleem met de automatische generatie van EditItemTemplate
formView is dat hiermee webbesturingselementen voor tekstvakken worden weergegeven voor velden die alleen-lezen zijn, zoals CategoryName
en SupplierName
. We zien hoe we dit binnenkort kunnen nagaan.
De Tekstvak controls in EditItemTemplate
hebben hun Text
eigenschap gebonden aan de waarde van hun bijbehorende gegevensveld met behulp van gegevensbinding met twee richtingen. Gegevensbinding in twee richtingen, aangeduid door <%# Bind("dataField") %>
, voert gegevensbindingen uit, zowel bij het binden van gegevens aan de sjabloon als bij het invullen van de parameters van ObjectDataSource voor het invoegen of bewerken van records. Dat wil zeggen, wanneer de gebruiker op de knop Bewerken klikt vanuit de ItemTemplate
, retourneert de Bind()
-methode de opgegeven gegevensveldwaarde. Nadat de gebruiker de wijzigingen heeft aangebracht en op Bijwerken heeft geklikt, worden de waarden die zijn gepost en die overeenkomen met de gegevensvelden die zijn opgegeven met Bind()
, toegepast op de UpdateParameters
van de ObjectDataSource. Alternatief haalt eenrichtingsgegevensbinding, aangeduid door <%# Eval("dataField") %>
, alleen de waarden van het gegevensveld op wanneer gegevens aan de sjabloon worden gekoppeld en retourneert de door de gebruiker ingevoerde waarden niet aan de parameters van de gegevensbron bij de postback.
De volgende declaratieve markering toont de EditItemTemplate
van de FormView. Houd er rekening mee dat de Bind()
methode hier wordt gebruikt in de syntaxis van de gegevensbinding en dat de webbesturingselementen Bijwerken en Annuleren de CommandName
eigenschappen dienovereenkomstig hebben ingesteld.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <EditItemTemplate> ProductID: <asp:Label ID="ProductIDLabel1" runat="server" Text="<%# Eval("ProductID") %>"></asp:Label><br /> ProductName: <asp:TextBox ID="ProductNameTextBox" runat="server" Text="<%# Bind("ProductName") %>"> </asp:TextBox><br /> SupplierID: <asp:TextBox ID="SupplierIDTextBox" runat="server" Text="<%# Bind("SupplierID") %>"> </asp:TextBox><br /> CategoryID: <asp:TextBox ID="CategoryIDTextBox" runat="server" Text="<%# Bind("CategoryID") %>"> </asp:TextBox><br /> QuantityPerUnit: <asp:TextBox ID="QuantityPerUnitTextBox" runat="server" Text="<%# Bind("QuantityPerUnit") %>"> </asp:TextBox><br /> UnitPrice: <asp:TextBox ID="UnitPriceTextBox" runat="server" Text="<%# Bind("UnitPrice") %>"> </asp:TextBox><br /> UnitsInStock: <asp:TextBox ID="UnitsInStockTextBox" runat="server" Text="<%# Bind("UnitsInStock") %>"> </asp:TextBox><br /> UnitsOnOrder: <asp:TextBox ID="UnitsOnOrderTextBox" runat="server" Text="<%# Bind("UnitsOnOrder") %>"> </asp:TextBox><br /> ReorderLevel: <asp:TextBox ID="ReorderLevelTextBox" runat="server" Text="<%# Bind("ReorderLevel") %>"> </asp:TextBox><br /> Discontinued: <asp:CheckBox ID="DiscontinuedCheckBox" runat="server" Checked="<%# Bind("Discontinued") %>" /><br /> CategoryName: <asp:TextBox ID="CategoryNameTextBox" runat="server" Text="<%# Bind("CategoryName") %>"> </asp:TextBox><br /> SupplierName: <asp:TextBox ID="SupplierNameTextBox" runat="server" Text="<%# Bind("SupplierName") %>"> </asp:TextBox><br /> <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update" Text="Update"> </asp:LinkButton> <asp:LinkButton ID="UpdateCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"> </asp:LinkButton> </EditItemTemplate> <InsertItemTemplate> ... </InsertItemTemplate> <ItemTemplate> ... </ItemTemplate> </asp:FormView>
Onze EditItemTemplate
, op dit moment, zal een uitzondering veroorzaken als we proberen deze te gebruiken. Het probleem is dat de velden CategoryName
en SupplierName
worden weergegeven als tekstvakken webcontroles in de EditItemTemplate
. We moeten deze tekstvakken wijzigen in Labels of helemaal verwijderen. Laten we ze gewoon geheel uit de EditItemTemplate
verwijderen.
Afbeelding 23 toont de FormView in een browser nadat op de knop Bewerken is geklikt voor Chai. Houd er rekening mee dat de SupplierName
- en CategoryName
-velden die in de ItemTemplate
worden weergegeven niet meer aanwezig zijn, omdat we ze zojuist uit de EditItemTemplate
hebben verwijderd. Wanneer op de knop Bijwerken wordt geklikt, doorloopt de FormView dezelfde reeks stappen als de besturingselementen GridView en DetailsView.
Afbeelding 23: Standaard wordt EditItemTemplate
elk bewerkbaar productveld weergegeven als een tekstvak of selectievakje (klik om de volledige afbeelding weer te geven)
Wanneer op de knop Invoegen wordt geklikt, vindt een postback plaats van FormView ItemTemplate
. Er zijn echter geen gegevens gebonden aan de FormView omdat er een nieuwe record wordt toegevoegd. De InsertItemTemplate
interface bevat de webbesturingselementen voor het toevoegen van een nieuwe record, samen met de knoppen Invoegen en Annuleren. De standaardwaarde InsertItemTemplate
die door Visual Studio wordt gegenereerd, bevat een tekstvak voor elk niet-Booleaanse waardeveld en een selectievakje voor elk booleaanse waardeveld, vergelijkbaar met de automatisch gegenereerde EditItemTemplate
interface. De tekstvakbesturingselementen hebben hun Text
eigenschap gebonden aan de waarde van het bijbehorende gegevensveld met behulp van tweerichtingsgegevensbinding.
De volgende declaratieve markering toont de InsertItemTemplate
van de FormView. Houd er rekening mee dat de Bind()
methode hier wordt gebruikt in de syntaxis van de gegevensbinding en dat de webbesturingselementen Invoegen en Annuleren de CommandName
eigenschappen dienovereenkomstig hebben ingesteld.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <EditItemTemplate> ... </EditItemTemplate> <InsertItemTemplate> ProductName: <asp:TextBox ID="ProductNameTextBox" runat="server" Text="<%# Bind("ProductName") %>"> </asp:TextBox><br /> SupplierID: <asp:TextBox ID="SupplierIDTextBox" runat="server" Text="<%# Bind("SupplierID") %>"> </asp:TextBox><br /> CategoryID: <asp:TextBox ID="CategoryIDTextBox" runat="server" Text="<%# Bind("CategoryID") %>"> </asp:TextBox><br /> QuantityPerUnit: <asp:TextBox ID="QuantityPerUnitTextBox" runat="server" Text="<%# Bind("QuantityPerUnit") %>"> </asp:TextBox><br /> UnitPrice: <asp:TextBox ID="UnitPriceTextBox" runat="server" Text="<%# Bind("UnitPrice") %>"> </asp:TextBox><br /> UnitsInStock: <asp:TextBox ID="UnitsInStockTextBox" runat="server" Text="<%# Bind("UnitsInStock") %>"> </asp:TextBox><br /> UnitsOnOrder: <asp:TextBox ID="UnitsOnOrderTextBox" runat="server" Text="<%# Bind("UnitsOnOrder") %>"> </asp:TextBox><br /> ReorderLevel: <asp:TextBox ID="ReorderLevelTextBox" runat="server" Text="<%# Bind("ReorderLevel") %>"> </asp:TextBox><br /> Discontinued: <asp:CheckBox ID="DiscontinuedCheckBox" runat="server" Checked="<%# Bind("Discontinued") %>" /><br /> CategoryName: <asp:TextBox ID="CategoryNameTextBox" runat="server" Text="<%# Bind("CategoryName") %>"> </asp:TextBox><br /> SupplierName: <asp:TextBox ID="SupplierNameTextBox" runat="server" Text="<%# Bind("SupplierName") %>"> </asp:TextBox><br /> <asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert" Text="Insert"> </asp:LinkButton> <asp:LinkButton ID="InsertCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"> </asp:LinkButton> </InsertItemTemplate> <ItemTemplate> ... </ItemTemplate> </asp:FormView>
Er is een subtiliteit bij de automatische generatie van de InsertItemTemplate
door de FormView. Specifiek worden de TextBox-webbesturingselementen zelfs gemaakt voor velden die alleen-lezen zijn, zoals CategoryName
en SupplierName
. Net zoals bij de EditItemTemplate
, moeten we deze TextBoxen verwijderen uit de InsertItemTemplate
.
Afbeelding 24 toont de FormView in een browser bij het toevoegen van een nieuw product, Acme Coffee. Houd er rekening mee dat de SupplierName
en CategoryName
velden die in de ItemTemplate
worden getoond niet meer aanwezig zijn, omdat we ze zojuist hebben verwijderd. Wanneer op de knop Invoegen wordt geklikt, doorloopt de FormView dezelfde reeks stappen als het besturingselement DetailsView en voegt u een nieuwe record toe aan de Products
tabel. In afbeelding 25 ziet u de details van het Acme Coffee-product in de FormView nadat het is ingevoegd.
Afbeelding 24: De InsertItemTemplate
Insert Interface van FormView dicteert (klik om de afbeelding op volledige grootte weer te geven)
Afbeelding 25: De details voor nieuw product, Acme Coffee, worden weergegeven in de FormView (klik om de volledige afbeelding weer te geven)
Door de interfaces met het kenmerk Alleen-lezen, bewerken en invoegen in drie afzonderlijke sjablonen te scheiden, biedt de FormView een nauwkeurigere mate van controle over deze interfaces dan de DetailsView en GridView.
Opmerking
Net als de eigenschap DetailsView geeft de eigenschap van FormView CurrentMode
de interface aan die wordt weergegeven en DefaultMode
de bijbehorende eigenschap geeft de modus aan waarnaar de FormView terugkeert nadat een bewerking of invoeging is voltooid.
Samenvatting
In deze zelfstudie hebben we de basisbeginselen onderzocht van het invoegen, bewerken en verwijderen van gegevens met behulp van GridView, DetailsView en FormView. Alle drie deze besturingselementen bieden een bepaald niveau van ingebouwde mogelijkheden voor het wijzigen van gegevens die kunnen worden gebruikt zonder dat u één regel code hoeft te schrijven op de ASP.NET pagina dankzij de besturingselementen voor het gegevensweb en de ObjectDataSource. De eenvoudige technieken voor het aanwijzen en klikken geven echter een redelijk zwakke en naïve gebruikersinterface voor het wijzigen van gegevens weer. Als u validatie wilt bieden, programmatische waarden injecteert, uitzonderingen probleemloos wilt afhandelen, de gebruikersinterface wilt aanpassen, enzovoort, moet u vertrouwen op een afzondering van technieken die in de volgende zelfstudies worden besproken.
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.