Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här självstudien får vi se hur du mappar metoderna Insert(), Update() och Delete() för en ObjectDataSource till metoderna för BLL-klasser, samt hur du konfigurerar kontrollerna GridView, DetailsView och FormView för att tillhandahålla funktioner för dataändring.
Inledning
Under de senaste självstudierna har vi undersökt hur du visar data på en ASP.NET sida med hjälp av kontrollerna GridView, DetailsView och FormView. Dessa kontroller fungerar helt enkelt med data som skickas till dem. Dessa styr vanligtvis åtkomst till data med hjälp av en datakällkontroll, till exempel ObjectDataSource. Vi har sett hur ObjectDataSource fungerar som en proxy mellan ASP.NET-sidan och underliggande data. När en GridView behöver visa data anropar den sin ObjectDataSource-metod Select()
, som i sin tur anropar en metod från vårt BLL (Business Logic Layer), som anropar en metod i lämpligt Data Access Layer-tabell (DAL) TableAdapter, som i sin tur skickar en SELECT
fråga till Northwind-databasen.
Kom ihåg att när vi skapade TableAdapters i DAL i vår första självstudie lade Visual Studio automatiskt till metoder för att infoga, uppdatera och ta bort data från den underliggande databastabellen. Dessutom, i Skapa ett affärslogiklager, har vi utformat metoder i BLL som anropade dessa DAL-metoder för dataändring.
Förutom metoden Select()
har Insert()
ObjectDataSource även metoderna , Update()
och Delete()
. Precis som Select()
metoden kan dessa tre metoder mappas till metoder i ett underliggande objekt. När kontrollerna GridView, DetailsView och FormView är konfigurerade för att infoga, uppdatera eller ta bort data får du ett användargränssnitt för att ändra underliggande data. Det här användargränssnittet anropar Insert()
, Update()
och Delete()
metoderna av ObjectDataSource, som sedan anropar det underliggande objektets associerade metoder (se Figur 1).
Bild 1: ObjectDataSources Insert()
, Update()
och Delete()
metoder fungerar som en proxy i BLL-filen (Klicka om du vill visa en bild i full storlek)
I den här självstudien får vi se hur du mappar ObjectDataSources Insert()
, Update()
och Delete()
-metoder till metoder för klasser i BLL, samt hur du konfigurerar kontrollerna GridView, DetailsView och FormView för att tillhandahålla funktioner för dataändring.
Steg 1: Skapa webbsidorna Infoga, Uppdatera och Ta bort
Innan vi börjar utforska hur du infogar, uppdaterar och tar bort data ska vi först ta en stund att skapa de ASP.NET sidor i vårt webbplatsprojekt som vi behöver för den här självstudien och de kommande flera. Börja med att lägga till en ny mapp med namnet EditInsertDelete
. Lägg sedan till följande ASP.NET sidor i mappen och se till att associera varje sida med Site.master
huvudsidan:
Default.aspx
Basics.aspx
DataModificationEvents.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
Bild 2: Lägg till ASP.NET-sidorna för Data Modification-Related-självstudierna
Precis som i de andra mapparna kommer Default.aspx
i EditInsertDelete
-mappen att lista självstudierna i dess avsnitt. Kom ihåg att SectionLevelTutorialListing.ascx
användarkontrollen innehåller den här funktionen. Lägg därför till den här användarkontrollen genom att Default.aspx
dra den från Solution Explorer till sidans designvy.
Bild 3: Lägg till SectionLevelTutorialListing.ascx
användarkontrollen Default.aspx
i (Klicka om du vill visa en bild i full storlek)
Slutligen lägger du till sidorna som poster i Web.sitemap
-filen. Mer specifikt lägger du till följande markering efter den anpassade formateringen <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>
Efter att du har uppdaterat Web.sitemap
, ta en stund att besöka självstudiewebbplatsen via en webbläsare. Menyn till vänster innehåller nu alternativ för redigering, infogning och borttagning av handledningar.
Bild 4: Webbplatsöversikten innehåller nu entréer för handledningarna Infoga, Redigera och Ta bort
Steg 2: Lägga till och konfigurera ObjectDataSource-kontrollen
Eftersom GridView, DetailsView och FormView skiljer sig åt i sina funktioner för datamodifiering och layout ska vi undersöka var och en individuellt. I stället för att ha varje kontroll med hjälp av sin egen ObjectDataSource ska vi dock bara skapa en enda ObjectDataSource som alla tre kontrollexemplen kan dela.
Öppna sidan Basics.aspx
, dra en ObjectDataSource från verktygslådan till designern och klicka på länken för att konfigurera datakällan från dess smarta tagg.
ProductsBLL
Eftersom är den enda BLL-klassen som tillhandahåller redigerings-, infognings- och borttagningsmetoder konfigurerar du ObjectDataSource för att använda den här klassen.
Konfigurera ObjectDataSource för att använda klassen ProductsBLL
Bild 5: Konfigurera ObjectDataSource att använda ProductsBLL
klassen (Klicka om du vill visa en bild i full storlek)
På nästa skärm kan vi ange vilka metoder i ProductsBLL
klassen som mappas till ObjectDataSources Select()
, Insert()
, Update()
och Delete()
genom att välja lämplig flik och välja metoden i listrutan. Bild 6, som bör se bekant ut vid det här laget, mappar ObjectDataSource-metoden Select()
till ProductsBLL
klassens GetProducts()
-metod. Metoderna Insert()
, Update()
och Delete()
kan konfigureras genom att välja lämplig flik i listan längst upp.
Bild 6: Låt ObjectDataSource returnera alla produkter (klicka om du vill visa en bild i full storlek)
Figurerna 7, 8 och 9 visar flikarna UPDATE, INSERT och DELETE för ObjectDataSource. Konfigurera dessa flikar så att Insert()
metoderna , Update()
, och Delete()
anropar ProductsBLL
klassens UpdateProduct
, AddProduct
respektive DeleteProduct
metoder.
Bild 7: Mappa ObjectDataSource-metoden Update()
till ProductBLL
klassens UpdateProduct
metod (Klicka om du vill visa en bild i full storlek)
Bild 8: Mappa ObjectDataSource-metoden Insert()
till klassens lägg till-metod ProductBLL
Product
(Klicka om du vill visa en bild i full storlek)
Bild 9: Mappa ObjectDataSource-metoden Delete()
till ProductBLL
klassens DeleteProduct
metod (Klicka om du vill visa en bild i full storlek)
Du kanske har märkt att listrutorna på flikarna UPDATE, INSERT och DELETE redan hade valt dessa metoder. Detta är tack vare vår användning av DataObjectMethodAttribute
som dekorerar metoderna för ProductsBLL
. Metoden DeleteProduct har till exempel följande signatur:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
...
}
Attributet DataObjectMethodAttribute
anger syftet med varje metod oavsett om det är för att välja, infoga, uppdatera eller ta bort och om det är standardvärdet eller inte. Om du utelämnade dessa attribut när du skapade dina BLL-klasser måste du manuellt välja metoderna från flikarna UPDATE, INSERT och DELETE.
När du har kontrollerat att lämpliga ProductsBLL
metoder har mappats till ObjectDataSources Insert()
metoder , Update()
och Delete()
klickar du på Slutför för att slutföra guiden.
Undersöka ObjectDataSources markup
När du har konfigurerat ObjectDataSource via guiden går du till källvyn för att undersöka den genererade deklarativa markeringen. Taggen <asp:ObjectDataSource>
anger det underliggande objektet och de metoder som ska anropas. Dessutom finns DeleteParameters
, UpdateParameters
och InsertParameters
som mappas till indataparametrarna för ProductsBLL
-klassens AddProduct
, UpdateProduct
och DeleteProduct
metoder.
<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 innehåller en parameter för var och en av indataparametrarna för dess associerade metoder, precis som en lista med SelectParameter
s finns när ObjectDataSource har konfigurerats för att anropa en select-metod som förväntar sig en indataparameter (till exempel GetProductsByCategoryID(categoryID)
). Som vi snart kommer att se anges värdena för dessa DeleteParameters
, UpdateParameters
och InsertParameters
automatiskt av GridView, DetailsView och FormView innan du anropar ObjectDataSources Insert()
, Update()
eller Delete()
-metod. Dessa värden kan också anges programmatiskt vid behov, som vi kommer att diskutera i en framtida handledning.
En bieffekt av att använda guiden för att konfigurera till ObjectDataSource är att Visual Studio anger egenskapen OldValuesParameterFormatString till original_{0}
. Det här egenskapsvärdet används för att inkludera de ursprungliga värdena för de data som redigeras och är användbart i två scenarier:
- Om användarna kan ändra primärnyckelvärdet när de redigerar en post. I det här fallet måste både det nya primärnyckelvärdet och det ursprungliga primärnyckelvärdet anges så att posten med det ursprungliga primärnyckelvärdet kan hittas och dess värde uppdateras i enlighet med detta.
- När du använder optimistisk samtidighet. Optimistisk samtidighet är en teknik som säkerställer att två samtidiga användare inte skriver över varandras ändringar och är ämnet för en framtida självstudie.
Egenskapen OldValuesParameterFormatString
anger namnet på indataparametrarna i det underliggande objektets uppdaterings- och borttagningsmetoder för de ursprungliga värdena. Vi diskuterar den här egenskapen och dess syfte i detalj när vi utforskar optimistisk samtidighet. Jag tar dock upp det nu, eftersom våra BLL-metoder inte förväntar sig de ursprungliga värdena och därför är det viktigt att vi tar bort den här egenskapen.
OldValuesParameterFormatString
Om egenskapen är inställd på något annat än standardvärdet ({0}
) uppstår ett fel när en datawebbkontroll försöker anropa ObjectDataSources Update()
eller Delete()
-metoder eftersom ObjectDataSource försöker skicka både eller UpdateParameters
DeleteParameters
angivna samt ursprungliga värdeparametrar.
Om detta inte är särskilt tydligt i det här läget, oroa dig inte, vi kommer att undersöka den här egenskapen och dess nytta i en framtida handledning. För tillfället är du bara säker på att antingen ta bort den här egenskapsdeklarationen helt från den deklarativa syntaxen eller ange värdet till standardvärdet ({0}).
Anmärkning
Om du helt enkelt avmarkerar egenskapsvärdet OldValuesParameterFormatString
från fönstret Egenskaper i designvyn finns egenskapen fortfarande i den deklarativa syntaxen, men anges till en tom sträng. Detta kommer tyvärr fortfarande att leda till samma problem som diskuterats ovan. Ta därför bort egenskapen helt och hållet från den deklarativa syntaxen eller ange värdet till standardvärdet från {0}
fönstret Egenskaper.
Steg 3: Lägga till en datawebbkontroll och konfigurera den för dataändring
När ObjectDataSource har lagts till på sidan och konfigurerats är vi redo att lägga till datawebbkontroller på sidan för att både visa data och tillhandahålla ett sätt för slutanvändaren att ändra dem. Vi tittar separat på GridView, DetailsView och FormView eftersom dessa datawebbkontroller skiljer sig åt i deras funktioner och konfiguration av dataändringar.
Som vi ser i resten av den här artikeln är det verkligen lika enkelt att lägga till mycket grundläggande redigering, infoga och ta bort stöd via kontrollerna GridView, DetailsView och FormView som att kontrollera ett par kryssrutor. Det finns många subtiliteter och gränsfall i verkligheten som gör att tillhandahålla sådana funktioner mer involverade än att bara peka och klicka. Den här självstudien fokuserar dock enbart på att demonstrera enkla datamodifieringsmöjligheter. Framtida handledningar kommer att undersöka problem som utan tvekan kommer att uppstå i en verklig miljö.
Ta bort data från GridView
Börja med att dra en GridView från verktygslådan till designern. Sedan binder du ObjectDataSource till GridView genom att välja den i listrutan i GridViews smarta tagg. Vid denna punkt kommer GridViews deklarativa markup-kod att vara:
<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>
Att binda GridView till ObjectDataSource via den smarta taggen har två fördelar:
- BoundFields och CheckBoxFields skapas automatiskt för vart och ett av fälten som returneras av ObjectDataSource. Dessutom anges egenskaperna för BoundField och CheckBoxField baserat på det underliggande fältets metadata. Fälten
ProductID
,CategoryName
ochSupplierName
markeras till exempel som skrivskyddade iProductsDataTable
och bör därför inte vara uppdaterade när du redigerar. För att hantera detta är dessa BoundFields ReadOnly-egenskaper inställda påtrue
. -
Egenskapen DataKeyNames tilldelas det underliggande objektets primära nyckelfält. Detta är viktigt när du använder GridView för att redigera eller ta bort data, eftersom den här egenskapen anger det fält (eller en uppsättning fält) som unikt identifierar varje post. Mer information om egenskapen, gå tillbaka till handledningen
DataKeyNames
.
Även om GridView kan bindas till ObjectDataSource via fönstret Egenskaper eller deklarativ syntax, måste du manuellt lägga till rätt BoundField och DataKeyNames
-markering.
GridView-kontrollen ger inbyggt stöd för redigering och borttagning på radnivå. När du konfigurerar en GridView för att stödja borttagning läggs en kolumn med ta bort knappar. När slutanvändaren klickar på knappen Ta bort för en viss rad, följer en postback och GridView utför följande steg:
- ObjectDataSources värde(n) tilldelas
DeleteParameters
- ObjectDataSource-metoden anropas
Delete()
och tar bort den angivna posten - GridView binds om till ObjectDataSource genom att anropa dess
Select()
metod
De värden som tilldelats DeleteParameters
är de värden som finns i fältet/fälten DataKeyNames
för raden vars borttagningsknapp har klickats på. Därför är det viktigt att en GridView-egenskap DataKeyNames
är korrekt inställd. Om den saknas kommer den DeleteParameters
att tilldelas ett null
värde i steg 1, vilket i sin tur inte kommer att resultera i några raderade poster i steg 2.
Anmärkning
Samlingen DataKeys
lagras i GridView-kontrolltillståndet DataKeys
, vilket innebär att värdena kommer att kommas ihåg över postback även om GridView-vytillståndet har inaktiverats. Det är dock mycket viktigt att visningstillståndet fortfarande är aktiverat för GridViews som stöder redigering eller borttagning (standardbeteendet). Om du anger egenskapen GridView till EnableViewState
fungerar redigerings- och borttagningsbeteendet false
bra för en enskild användare, men om det finns samtidiga användare som tar bort data finns det en möjlighet att dessa samtidiga användare oavsiktligt kan ta bort eller redigera poster som de inte har för avsikt.
Samma varning gäller även för DetailsViews och FormViews.
Om du vill lägga till borttagningsfunktioner i en GridView går du helt enkelt till den smarta taggen och markerar kryssrutan Aktivera borttagning.
Bild 10: Markera kryssrutan Aktivera borttagning
Om du markerar kryssrutan Aktivera borttagning från den smarta taggen läggs ett Kommandofält till i GridView. CommandField renderar en kolumn i GridView med knappar för att utföra en eller flera av följande uppgifter: välja en post, redigera en post och ta bort en post. Vi såg tidigare att CommandField var i aktion med att välja poster i huvud-/detaljguiden med hjälp av en valbar huvudrutnätvy med en details DetailView-självstudie .
Kommandofältet innehåller ett antal ShowXButton
egenskaper som anger vilken serie knappar som visas i Kommandofältet. Genom att markera kryssrutan Aktivera borttagning har en CommandField med egenskapen ShowDeleteButton
och true
lagts till i GridViews kolumnsamling.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
Tro det eller ej nu, vi är klara med att lägga till stöd för borttagning i GridView! Som bild 11 visar visas en kolumn med Ta bort knappar när du besöker den här sidan via en webbläsare.
Bild 11: Kommandofältet lägger till en kolumn med borttagningsknappar (Klicka om du vill visa en bild i full storlek)
Om du har byggt den här självstudien från grunden på egen hand kommer ett undantag att resultera när du testar denna sida genom att klicka på knappen Ta bort. Fortsätt läsa för att lära dig varför dessa undantag har genererats och hur du åtgärdar dem.
Anmärkning
Om du använder nedladdningen som medföljer den här handledningen har dessa problem redan tagits hand om. Jag rekommenderar dock att du läser igenom informationen nedan för att identifiera problem som kan uppstå och lämpliga lösningar.
Om du när du försöker ta bort en produkt får ett undantag vars meddelande liknar "ObjectDataSource 'ObjectDataSource1' inte kunde hitta en icke-generisk metod 'DeleteProduct' som har parametrar: productID, original_ProductID", har du förmodligen glömt att ta bort OldValuesParameterFormatString
egenskapen från ObjectDataSource. Med den OldValuesParameterFormatString
angivna egenskapen försöker ObjectDataSource skicka in båda productID
parametrarna och original_ProductID
indataparametrarna till DeleteProduct
metoden.
DeleteProduct
accepterar dock bara en enda indataparameter, därav undantaget. Om du OldValuesParameterFormatString
tar bort egenskapen (eller anger den till {0}
) instrueras ObjectDataSource att inte försöka skicka den ursprungliga indataparametern.
Bild 12: Kontrollera att egenskapen OldValuesParameterFormatString
har rensats (klicka om du vill visa en bild i full storlek)
Även om du hade tagit bort OldValuesParameterFormatString
egenskapen får du fortfarande ett undantag när du försöker ta bort en produkt med meddelandet : "DELETE-instruktionen stod i konflikt med REFERENS-villkoret "FK_Order_Details_Products". Northwind-databasen innehåller en sekundärnyckelbegränsning mellan Order Details
tabellen och Products
, vilket innebär att en produkt inte kan tas bort från systemet om det finns en eller flera poster för den Order Details
i tabellen. Eftersom varje produkt i Northwind-databasen har minst en post i Order Details
kan vi inte ta bort några produkter förrän vi först tar bort produktens associerade orderinformationsposter.
Bild 13: En begränsning för främmande nyckel förbjuder borttagning av produkter (klicka för att visa bilden i full storlek)
I vår handledning tar vi bort alla poster från tabellen Order Details
. I ett verkligt program behöver vi antingen:
- Ha en annan skärm för att hantera beställningsinformation.
- Utöka metoden så att den
DeleteProduct
innehåller logik för att ta bort den angivna produktens orderinformation - Ändra SQL-frågan som används av TableAdapter så att den innehåller borttagning av den angivna produktens orderinformation
Nu ska vi ta bort alla poster från Order Details
tabellen för att kringgå villkoret för sekundärnyckeln. Gå till Server Explorer i Visual Studio, högerklicka på NORTHWND.MDF
noden och välj Ny fråga. Kör sedan följande SQL-instruktion i frågefönstret: DELETE FROM [Order Details]
Bild 14: Ta bort alla poster från Order Details
tabellen (Klicka för att visa bilden i full storlek)
Efter att du har rensat tabellen och klickat på knappen Ta bort tas produkten bort utan problem. Om klickandet på knappen Ta bort inte resulterar i att produkten tas bort, kontrollera att GridView-egenskapen DataKeyNames
är inställd på primärnyckelfältet (ProductID
).
Anmärkning
När du klickar på knappen Ta bort sker en återkoppling och posten tas bort. Detta kan vara farligt eftersom det är lätt att oavsiktligt klicka på fel rads Ta bort-knapp. I en framtida handledning kommer vi att se hur vi lägger till en bekräftelse på klientsidan när vi tar bort en post.
Redigera data med GridView
Förutom att ta bort ger GridView-kontrollen även inbyggt redigeringsstöd på radnivå. När du konfigurerar en GridView som stöd för redigering läggs en kolumn med Redigera knappar till. Om du klickar på knappen Redigera på en rad från slutanvändarens perspektiv blir raden redigerbar, cellerna omvandlas till textrutor som innehåller de befintliga värdena och ersätter knappen Redigera med knapparna Uppdatera och Avbryt. När de har gjort önskade ändringar kan slutanvändaren klicka på knappen Uppdatera för att checka in ändringarna eller knappen Avbryt för att ta bort dem. När du har klickat på Uppdatera eller Avbryt återgår GridView till dess förredigeringstillstånd.
Från vårt perspektiv som sidutvecklare, när slutanvändaren klickar på knappen Redigera för en viss rad, följer en postback och GridView utför följande steg:
- GridView:ens
EditItemIndex
-egenskap tilldelas indexet för raden vars redigeringsknapp har klickats - GridView binds om till ObjectDataSource genom att anropa dess
Select()
metod - Radindexet som motsvarar
EditItemIndex
återges i "redigerarläge". I detta läge ersätts knappen Redigera med knapparna Uppdatera och Avbryt, och BoundFields varsReadOnly
egenskaper är False (standard) visas som TextBox Web-kontroller därText
egenskaper är tilldelade datafältens värden.
Nu returneras markup till webbläsaren, som möjliggör för slutanvändaren att göra ändringar i radens data. När användaren klickar på knappen Uppdatera sker ett återanrop och GridView utför följande steg:
- Värdena från ObjectDataSource tilldelas de värden som anges av slutanvändaren i GridViews redigeringsgränssnitt
- ObjectDataSource-metoden anropas
Update()
och uppdaterar den angivna posten - GridView binds om till ObjectDataSource genom att anropa dess
Select()
metod
De primära nyckelvärden som tilldelats UpdateParameters
i steg 1 kommer från de värden som anges i DataKeyNames
egenskapen, medan de icke-primära nyckelvärdena kommer från texten i TextBox Web-kontrollerna för den redigerade raden. Precis som vid borttagning är det viktigt att en GridView-egenskap DataKeyNames
är korrekt inställd. Om det saknas kommer primärnyckelvärdet UpdateParameters
att tilldelas ett null
värde i steg 1, vilket i sin tur inte resulterar i några uppdaterade poster i steg 2.
Redigeringsfunktioner kan aktiveras genom att bara markera kryssrutan Aktivera redigering i GridViews smarta tagg.
Bild 15: Markera kryssrutan Aktivera redigering
Om du markerar kryssrutan Aktivera redigering läggs ett Kommandofält (om det behövs) och dess ShowEditButton
egenskap anges till true
. Som vi såg tidigare innehåller CommandField ett antal ShowXButton
egenskaper som anger vilken serie knappar som visas i Kommandofältet. Om du markerar kryssrutan Aktivera redigering läggs ShowEditButton
egenskapen till i det befintliga Kommandofältet:
<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>
Det är allt som krävs för att lägga till rudimentärt redigeringsstöd. Som bild 16 visar, är redigeringsgränssnittet ganska primitivt. Varje BoundField vars ReadOnly
-egenskap är inställd på false
(standardvärdet) återges som en textruta. Detta inkluderar fält som CategoryID
och SupplierID
, som är nycklar till andra tabeller.
Bild 16: Om du klickar på knappen Redigera i Chai visas raden i redigeringsläge (Klicka om du vill visa en bild i full storlek)
Förutom att be användarna redigera främmande nyckelvärden direkt, saknas redigeringsgränssnittet på följande sätt:
- Om användaren anger en
CategoryID
ellerSupplierID
som inte finns i databasenUPDATE
bryter den mot en begränsning för sekundärnyckel, vilket gör att ett undantag utlöses. - Redigeringsgränssnittet innehåller ingen verifiering. Om du inte anger ett obligatoriskt värde (till exempel
ProductName
), eller anger ett strängvärde där ett numeriskt värde förväntas (till exempel att ange "För mycket!" iUnitPrice
textrutan), genereras ett undantag. En framtida handledning kommer att undersöka hur du lägger till valideringskontroller i användargränssnittet för redigering. - För närvarande måste alla produktfält som inte är skrivskyddade ingå i GridView. Om vi skulle ta bort ett fält från GridView, till exempel
UnitPrice
, när vi uppdaterar data skulle GridView inte angeUnitPrice
UpdateParameters
värdet, vilket skulle ändra databaspostensUnitPrice
till ettNULL
värde. Om ett obligatoriskt fält, till exempelProductName
, tas bort från GridView, misslyckas uppdateringen på samma sätt med samma "Kolumn "ProductName" tillåter inte null-undantag som nämns ovan. - Formateringen för redigeringsgränssnittet lämnar mycket att önska.
UnitPrice
Visas med fyra decimaler. Helst skulleCategoryID
- ochSupplierID
-värdena innehålla listrutor som listar kategorierna och leverantörerna i systemet.
Det här är alla brister som vi måste leva med för tillfället, men som kommer att åtgärdas i framtida självstudier.
Infoga, redigera och ta bort data med DetailsView
Som vi har sett i tidigare självstudier visar DetailsView-kontrollen en post i taget och tillåter, precis som GridView, redigering och borttagning av den post som visas för närvarande. Både slutanvändarens erfarenhet av att redigera och ta bort objekt från en DetailsView och arbetsflödet från ASP.NET sidan är identisk med GridView. Där DetailsView skiljer sig från GridView är att den även ger inbyggt infogningsstöd.
Om du vill demonstrera funktionerna för dataändring i GridView börjar du med att lägga till en DetailsView på Basics.aspx
sidan ovanför det befintliga GridView och binda den till den befintliga ObjectDataSource via DetailsViews smarta tagg. Rensa sedan DetailsView-egenskaperna Height
och Width
och markera alternativet Aktivera paginering från den smarta taggen. Om du vill aktivera redigering, infogning och borttagning av stöd markerar du kryssrutan Aktivera redigering, Aktivera infogning och Aktivera borttagning i den smarta taggen.
Bild 17: Konfigurera DetailsView så att den stöder redigering, infogning och borttagning
Precis som med GridView lägger du till stöd för redigering, infogning eller borttagning av ett CommandField i DetailsView, som följande deklarativa syntax visar:
<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>
Observera att för DetailsView visas CommandField i slutet av samlingen Kolumner som standard. Eftersom DetailsView-fälten återges som rader visas Kommandofältet som en rad med knapparna Infoga, Redigera och Ta bort längst ned i DetailsView.
Bild 18: Konfigurera DetailsView så att den stöder redigering, infogning och borttagning (Klicka om du vill visa en bild i full storlek)
Om du klickar på knappen Ta bort startas samma sekvens av händelser som med GridView: en postback, följt av att DetailsView fyller sin ObjectDataSource baserat på DeleteParameters
och DataKeyNames
värdena, och avslutas med ett anrop av sin ObjectDataSource Delete()
metod, som faktiskt tar bort produkten från databasen. Redigering i DetailsView fungerar också på ett sätt som är identiskt med GridView.
För infogning visas slutanvändaren med en ny knapp som, när den klickas, återger DetailsView i "infogningsläge". Med "infogningsläge" ersätts knappen Ny med knapparna Infoga och Avbryt och endast de BoundFields vars InsertVisible
egenskap är inställd på true
(standard) visas. De datafält som identifieras som automatiskt inkrementella fält, exempel ProductID
, har sin egenskap InsertVisible inställd på false
vid bindning av DetailsView till datakällan via smarta taggen.
När du binder en datakälla till en DetailsView via den smarta taggen anger InsertVisible
Visual Studio egenskapen till false
endast för automatiskt inkrementella fält. Skrivskyddade fält, som CategoryName
och SupplierName
, visas i användargränssnittet i "infogningsläge" såvida inte deras InsertVisible
-egenskap uttryckligen är inställd på false
. Ta en stund att ange de här två fältens InsertVisible
egenskaper till false
, antingen via DetailsViews deklarativa syntax eller via länken Redigera fält i den smarta taggen. Bild 19 visar hur du ställer in InsertVisible
-egenskaperna till false
genom att klicka på länken Redigera fält.
Bild 19: Northwind Traders erbjuder nu Acme Tea (klicka för att visa bild i full storlek)
När du har angett InsertVisible
egenskaperna visar du sidan Basics.aspx
i en webbläsare och klickar på knappen Nytt. Bild 20 visar DetailsView när du lägger till en ny dryck, Acme Tea, till vår produktlinje.
Bild 20: Northwind Traders erbjuder nu Acme Tea (klicka för att visa bild i full storlek)
När du har angett informationen för Acme Tea och klickat på knappen Infoga, sker en postback och den nya posten läggs till i databastabellen Products
. Eftersom den här DetailsView listar produkterna i den ordning de finns i databastabellen måste vi gå till den sista produkten för att kunna se den nya produkten.
Bild 21: Information om Acme Tea (Klicka om du vill visa en bild i full storlek)
Anmärkning
Egenskapen CurrentMode i DetailsView anger vilket gränssnitt som visas och kan vara något av följande värden: Edit
, Insert
eller ReadOnly
.
Egenskapen DefaultMode anger läget som DetailsView återgår till när en redigering eller infogning har slutförts och är användbar för att visa en DetailsView som är permanent i redigerings- eller infogningsläge.
Peka och klicka på infognings- och redigeringsfunktionerna i DetailsView har samma begränsningar som GridView: användaren måste ange befintliga CategoryID
värden och SupplierID
värden via en textruta. Gränssnittet saknar valideringslogik. Alla produktfält som inte tillåter NULL
värden eller som inte har något standardvärde som anges på databasnivå måste ingå i infogningsgränssnittet. och så vidare.
De tekniker som vi kommer att undersöka för att utöka och förbättra GridViews redigeringsgränssnitt i framtida artiklar kan även tillämpas på DetailsView-kontrollens redigerings- och infogningsgränssnitt.
Använda FormView för ett mer flexibelt användargränssnitt för datamodifiering
FormView har inbyggt stöd för infogning, redigering och borttagning av data, men eftersom den använder mallar i stället för fält finns det ingen plats att lägga till BoundFields- eller CommandField-kontrollerna som används av kontrollerna GridView och DetailsView för att tillhandahålla datamodifieringsgränssnittet. I stället måste webbkontrollerna för att samla in användarindata när du lägger till ett nytt objekt eller redigerar ett befintligt objekt tillsammans med knapparna Nytt, Redigera, Ta bort, Infoga, Uppdatera och Avbryt läggas till manuellt i lämpliga mallar. Lyckligtvis skapar Visual Studio automatiskt det gränssnitt som behövs när du binder FormView till en datakälla via listrutan i den smarta taggen.
För att illustrera dessa tekniker börjar du med att lägga till en FormView på Basics.aspx
sidan och från Den smarta taggen i FormView binder du den till ObjectDataSource som redan har skapats. Detta genererar kontrollerna EditItemTemplate
, InsertItemTemplate
och ItemTemplate
för FormView med TextBox Web för att samla in användarens indata- och knappwebbkontroller för knapparna Ny, Redigera, Ta bort, Infoga, Uppdatera och Avbryt. Dessutom är egenskapen FormView DataKeyNames
inställd på primärnyckelfältet (ProductID
) för objektet som returneras av ObjectDataSource. Kontrollera slutligen alternativet Aktivera sidindelning i FormViews smarta tagg.
Följande visar deklarativ markup för FormView's ItemTemplate
efter att FormView har bundits till ObjectDataSource. Som standard är varje icke-booleskt värdeproduktfält bundet Text
till egenskapen för en etikettwebbkontroll medan varje booleskt värdefält (Discontinued
) är bundet Checked
till egenskapen för en inaktiverad CheckBox-webbkontroll. För att knapparna Ny, Redigera och Ta bort ska utlösa ett visst FormView-beteende när du klickar är det absolut nödvändigt att deras CommandName
värden anges till New
, Edit
Delete
respektive .
<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>
Bild 22 visar FormView ItemTemplate
när den visas via en webbläsare. Varje produktfält visas med knapparna Ny, Redigera och Ta bort längst ned.
Bild 22: Defaut FormView ItemTemplate
visar varje produktfält tillsammans med knapparna Ny, Redigera och Ta bort (Klicka om du vill visa en bild i full storlek)
Precis som med GridView och DetailsView, klickar du på knappen Ta bort eller någon knapp, LinkButton eller ImageButton vars CommandName
egenskap är inställd på Ta bort orsakar en postback, fyller i ObjectDataSources DeleteParameters
baserat på FormView-värdet DataKeyNames
och anropar ObjectDataSource-metoden Delete()
.
När Redigera-knappen klickas, sker ett postback-återanrop och data binds igen till EditItemTemplate
, som ansvarar för att rendera redigeringsgränssnittet. Det här gränssnittet innehåller webbkontroller för redigering av data tillsammans med knapparna Uppdatera och Avbryt. Standardvärdet EditItemTemplate
som genereras av Visual Studio innehåller en etikett för alla automatiskt inkrementella fält (ProductID
), en textruta för varje icke-booleskt värdefält och en kryssruta för varje booleskt värdefält. Det här beteendet liknar de automatiskt genererade BoundFields i kontrollerna GridView och DetailsView.
Anmärkning
Ett litet problem med den automatiska genereringen av EditItemTemplate
i FormView är att den renderar TextBox webbkontroller för fält som är skrivskyddade, till exempel CategoryName
och SupplierName
. Vi får se hur du tar hänsyn till detta inom kort.
TextBox-kontrollerna i EditItemTemplate
har sin Text
-egenskap bunden till värdet för motsvarande datafält genom dubbelriktad databindning. Dubbelriktad databindning, som anges av <%# Bind("dataField") %>
, utför databindning både när du binder data till mallen och när du fyller i ObjectDataSources parametrar för att infoga eller redigera poster. När användaren klickar på knappen Redigera från ItemTemplate
Bind()
returnerar metoden det angivna datafältvärdet. När användaren har gjort sina ändringar och klickar på uppdatera, tillämpas de värden som skickas tillbaka och som motsvarar de datafält som anges med Bind()
på ObjectDataSource's UpdateParameters
. Alternativt hämtar enkelriktad databindning, som anges av <%# Eval("dataField") %>
, endast datafältvärdena när data binds till mallen och returnerar inte de användarinmatningsvärdena till datakällans parametrar vid postback.
Här är den deklarativa markeringen som visar FormViews EditItemTemplate
. Observera att Bind()
metoden används i syntaxen för databindning här och att webbkontrollerna Uppdatera och Avbryt knapp har sina CommandName
egenskaper angivna.
<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>
I det här läget kommer vårt EditItemTemplate
att kasta ett undantagsfel om vi försöker använda det. Problemet är att fälten CategoryName
och SupplierName
återges som TextBox Web-kontroller i EditItemTemplate
. Vi behöver antingen ändra textrutorna till Etiketter eller ta bort dem helt och hållet. Vi tar helt enkelt bort dem helt från EditItemTemplate
.
Bild 23 visar FormView i en webbläsare när knappen Redigera har klickats för Chai. Observera att fälten SupplierName
och som visas i CategoryName
inte längre finns, eftersom vi just har tagit bort dem från ItemTemplate
EditItemTemplate
. När du klickar på knappen Uppdatera fortsätter FormView genom samma stegsekvens som kontrollerna GridView och DetailsView.
Bild 23: Som standard EditItemTemplate
visar varje redigerbart produktfält som en textruta eller kryssruta (Klicka om du vill visa en bild i full storlek)
När knappen Infoga har klickats på följer formvyns ItemTemplate
ett återanrop. Det finns dock inga data kopplade till FormView eftersom en ny post läggs till. Gränssnittet InsertItemTemplate
innehåller webbkontrollerna för att lägga till en ny post tillsammans med knapparna Infoga och Avbryt. Standardvärdet InsertItemTemplate
som genereras av Visual Studio innehåller en textruta för varje icke-booleskt värdefält och en kryssruta för varje booleskt värdefält, ungefär som det automatiskt genererade EditItemTemplate
gränssnittet. TextBox-kontrollerna har sin Text
egenskap bunden till värdet för motsvarande datafält med hjälp av dubbelriktad databindning.
Här är den deklarativa markeringen som visar FormViews InsertItemTemplate
. Observera att Bind()
metoden används i syntaxen för databindning här och att webbkontrollerna Infoga och Avbryt knapp har sina CommandName
egenskaper angivna.
<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>
Det finns en subtilitet i FormViews automatiska generering av InsertItemTemplate
. Mer specifikt skapas TextBox Web-kontrollerna även för de fält som är skrivskyddade, till exempel CategoryName
och SupplierName
. Precis som med EditItemTemplate
måste vi ta bort dessa textrutor från InsertItemTemplate
.
Bild 24 visar FormView i en webbläsare när du lägger till en ny produkt, Acme Coffee. Observera att fälten SupplierName
och CategoryName
som visas i ItemTemplate
inte längre finns, eftersom vi just har tagit bort dem. När knappen Infoga klickas fortsätter FormView genom samma stegsekvens som DetailsView-kontrollen och lägger till en ny post i Products
tabellen. Bild 25 visar Acme Coffee-produktens information i FormView efter att den har infogats.
Bild 24: InsertItemTemplate
Dikterar FormView-införandegränssnittet (Klicka för att visa bilden i full storlek)
Bild 25: Information om ny produkt, Acme Coffee, visas i FormView (Klicka om du vill visa en bild i full storlek)
Genom att avgränsa gränssnitt för endast läsning, redigering och infogning i tre separata mallar, ger FormView en finare grad av kontroll över dessa gränssnitt än DetailsView och GridView.
Anmärkning
Liksom DetailsView anger egenskapen FormView CurrentMode
gränssnittet som visas och dess DefaultMode
egenskap anger läget som FormView återgår till när en redigering eller infogning har slutförts.
Sammanfattning
I den här självstudien har vi gått igenom grunderna för att infoga, redigera och ta bort data med hjälp av GridView, DetailsView och FormView. Alla tre av dessa kontroller ger en viss nivå av inbyggda datamodifieringsfunktioner som kan användas utan att skriva en enda kodrad på ASP.NET-sidan tack vare datawebbkontrollerna och ObjectDataSource. De enkla peka och klicka-teknikerna renderar dock ett ganska skört och naivt användargränssnitt för datamodifiering. För att tillhandahålla validering, mata in programmatiska värden, hantera undantag på ett korrekt sätt, anpassa användargränssnittet och så vidare måste vi förlita oss på en mängd tekniker som kommer att diskuteras under de kommande självstudierna.
Lycka till med programmerandet!
Om författaren
Scott Mitchell, författare till sju ASP/ASP.NET-böcker och grundare av 4GuysFromRolla.com, har arbetat med Microsofts webbtekniker sedan 1998. Scott arbetar som oberoende konsult, tränare och författare. Hans senaste bok är Sams Teach Yourself ASP.NET 2.0 på 24 timmar. Han kan nås på mitchell@4GuysFromRolla.com.