Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
által Scott Mitchell
Megtudhatja, hogyan szúrhat be több adatbázisrekordot egyetlen műveletbe. A Felhasználói felület rétegben kiterjesztjük a GridView-t, hogy a felhasználó több új rekordot adjon meg. Az adatelérési rétegben egy tranzakció több beszúrási műveletét is körbefuttatjuk, hogy az összes beszúrás sikeres legyen, vagy az összes beszúrás vissza legyen állítva.
Bevezetés
A Batch-frissítési oktatóanyagban a GridView vezérlő testreszabását tekintettük át, hogy egy olyan felületet jelenítsünk meg, ahol több rekord is szerkeszthető volt. Az oldalt meglátogató felhasználó több módosítást is végrehajthat, majd egyetlen kattintással végrehajthat egy kötegfrissítést. Az olyan helyzetekben, amikor a felhasználók gyakran frissítik a rekordokat egy lépésben, az ilyen felületek számtalan kattintást és billentyűzetről egérre kapcsolót menthetnek, ha összehasonlítják azokat az alapértelmezett soronkénti szerkesztési funkciókat, amelyeket először az Adatok beszúrásának, frissítésének és törlésének áttekintése oktatóanyagban vizsgáltak meg.
Ez a fogalom rekordok hozzáadásakor is alkalmazható. Tegyük fel, hogy itt a Northwind Tradersnél általában olyan szállítóktól érkezik szállítmány, amelyek egy adott kategóriához tartozó számos terméket tartalmaznak. Például hat különböző tea- és kávétermék szállítmányt kaphatunk a Tokyo Traderstől. Ha egy felhasználó a DetailsView vezérlőn keresztül egyenként adja meg a hat terméket, újra és újra meg kell választania ugyanazt az értéket: ugyanazt a kategóriát (Italok), ugyanazt a szállítót (Tokyo Traders), ugyanazt a megszűnt értéket (False) és ugyanazt a rendelési értéket (0) kell választania. Ez az ismétlődő adatbevitel nem csak időigényes, hanem hibákra is hajlamos.
Egy kis munkával létrehozhatunk egy kötegbeszúró felületet, amely lehetővé teszi a felhasználó számára, hogy egyszer válassza ki a szállítót és a kategóriát, adjon meg egy sor terméknevet és egységárat, majd kattintson egy gombra az új termékek adatbázishoz való hozzáadásához (lásd az 1. ábrát). Az egyes termékek hozzáadásakor a ProductName és UnitPrice adatmezők azok az értékek, amelyeket a szövegmezőkbe írtak be, míg a CategoryID és SupplierID értékek az űrlap felső részén található legördülő listákból lesznek kijelölve. Az Discontinued és UnitsOnOrder értékek False és 0 kóddal rögzített értékekre vannak beállítva.
1. ábra: A Batch-beszúrási felület (ide kattintva megtekintheti a teljes méretű képet)
Ebben az oktatóanyagban létrehozunk egy oldalt, amely megvalósítja az 1. ábrán látható kötegbeszúró felületet. Az előző két oktatóanyag mintájára a módosításokat egy tranzakció keretébe fogjuk burkolni, hogy garantáljuk az atomitást. Lássunk hozzá!
1. lépés: A megjelenítési felület létrehozása
Ez az oktatóanyag egyetlen oldalból áll, amely két régióra oszlik: egy megjelenítési régióra és egy beszúrási régióra. A jelen lépésben létrehozott megjelenítési felület megjeleníti a termékeket egy GridView-ban, és tartalmaz egy folyamattermék-szállítás nevű gombot. Ha erre a gombra kattint, a megjelenítési felület lecserélődik a beszúró felületre, amely az 1. ábrán látható. A megjelenítési felület a Termékek hozzáadása a Szállításból vagy a Mégse gombra kattintás után tér vissza. A beszúrási felületet a 2. lépésben fogjuk létrehozni.
Ha olyan lapot hoz létre, amely két felülettel rendelkezik, amelyek közül egyszerre csak az egyik látható, az egyes felületek általában egy panel webvezérlőn belül vannak elhelyezve, amely tárolóként szolgál más vezérlők számára. Ezért lapunk két panelvezérlőt fog tartalmazni minden egyes felülethez.
Először nyissa meg a BatchInsert.aspx lapot a BatchData mappában, és húzzon egy panelt az eszközkészletből a Tervezőbe (lásd a 2. ábrát). Állítsa a Panel s tulajdonságát ID a következőre DisplayInterface: . Amikor hozzáadja a panelt a Tervezőhöz, annak Height és Width tulajdonságai 50px- és 125px-nek vannak beállítva. Törölje ezeket a tulajdonságértékeket a Tulajdonságok ablakból.
2. ábra: Húzzon egy panelt az eszközkészletből a Tervezőre (kattintson ide a teljes méretű kép megtekintéséhez)
Ezután húzza a Gomb és a GridView vezérlőt a panelre. Állítsa be a Button ID tulajdonságát és a ProcessShipment tulajdonságát, valamint a Text tulajdonságát a "Termékszállítás feldolgozása" értékre. Állítsa be a GridView ID tulajdonságát ProductsGrid értékre, és intelligens címkéjével kösse hozzá egy új, ProductsDataSource nevű ObjectDataSource-hoz. Konfigurálja az ObjectDataSource-t, hogy lekérje az adatait az ProductsBLL osztály GetProducts metódusából. Mivel ez a GridView csak az adatok megjelenítésére szolgál, állítsa a legördülő listákat az UPDATE, INSERT és DELETE fülön a (Nincs) értékre. Az Adatforrás konfigurálása varázsló befejezéséhez kattintson a Befejezés gombra.
3. ábra: Az osztály ProductsBLL metódusából GetProducts visszaadott adatok megjelenítése (ide kattintva megtekintheti a teljes méretű képet)
4. ábra: Állítsa a Drop-Down listákat az UPDATE, INSERT és DELETE tabulátorokban a (Nincs) értékre (ide kattintva megtekintheti a teljes méretű képet)
Az ObjectDataSource varázsló befejezése után a Visual Studio hozzáadja a BoundFields és a CheckBoxField mezőket a termékadatmezőkhöz. Távolítsa el az összeset, kivéve a ProductName, CategoryName, SupplierName, UnitPrice és a Discontinued mezőket. Bármilyen esztétikai testreszabást elvégezhet. Úgy döntöttem, hogy pénznemértékként formázom a UnitPrice mezőt, átrendeztem a mezőket, és átneveztem több mezőértéket HeaderText is. A GridView-t úgy is konfigurálhatja, hogy lapozási és rendezési támogatást is tartalmazzon a GridView intelligens címkéjében található Lapozás engedélyezése és Rendezés engedélyezése jelölőnégyzet bejelölésével.
A Panel, a Gomb, a GridView és az ObjectDataSource vezérlők hozzáadása és a GridView mezőinek testreszabása után a lap deklaratív korrektúrája az alábbihoz hasonlóan fog kinézni:
<asp:Panel ID="DisplayInterface" runat="server">
<p>
<asp:Button ID="ProcessShipment" runat="server"
Text="Process Product Shipment" />
</p>
<asp:GridView ID="ProductsGrid" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued">
<ItemStyle HorizontalAlign="Center" />
</asp:CheckBoxField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
</asp:Panel>
Vegye figyelembe, hogy a Gomb és a GridView jelölője a nyitó és a záró <asp:Panel> címkéken belül jelenik meg. Mivel ezek a vezérlők a DisplayInterface panelen belül találhatók, elrejthetjük őket úgy, hogy egyszerűen a Panel tulajdonságát Visible a következőre Falseállítjuk. A 3. lépés programozott módon módosítja a Panel tulajdonságát Visible egy gombkattintásra válaszul, hogy megjelenítse az egyik felületet, miközben elrejti a másikat.
Szánjon egy kis időt a haladás megtekintésére egy böngészőben. Ahogy az 5. ábrán látható, a GridView fölött egy Folyamat termékszállítmány gombnak kell megjelennie, amely egyszerre tíz terméket sorol fel.
5. ábra: A GridView felsorolja a termékek és ajánlatok rendezési és lapozási képességeit (kattintson ide a teljes méretű kép megtekintéséhez)
2. lépés: A beszúrási felület létrehozása
A megjelenítési felület elkészültével készen állunk a beszúrási felület létrehozására. Ebben az oktatóanyagban hozzunk létre egy beszúrási felületet, amely egyetlen szállítói és kategóriaértéket kér, majd lehetővé teszi, hogy a felhasználó legfeljebb öt terméknevet és egységár-értéket adjon meg. Ezzel a felülettel a felhasználó hozzáadhat egy-öt új terméket, amelyek mindegyike azonos kategóriával és szállítóval rendelkezik, de egyedi terméknevekkel és árakkal rendelkezik.
Először húzzon egy panelt az eszközkészletből a Tervezőre, és helyezze azt a meglévő DisplayInterface panel alá. Állítsa be az újonnan hozzáadott Panel ID tulajdonságát InsertingInterface értékre, és állítsa be a Visible tulajdonságát False értékre. Hozzáadunk egy kódot, amely a InsertingInterface panel Visible tulajdonságát True állítja be a 3. lépésben. Törölje a panel tulajdonságainak Height és Width értékeit is.
Ezután létre kell hoznunk az 1. ábrán látható beszúrási felületet. Ez a felület számos HTML-technikával hozható létre, de egy meglehetősen egyszerűt fogunk használni: egy négyoszlopos, hétsoros táblázatot.
Megjegyzés:
A HTML-elemek <table> jelölőjének megadásakor inkább a Forrás nézetet használom. Bár a Visual Studio rendelkezik eszközökkel <table> elemek tervezőn keresztüli hozzáadásához, a Tervező túlságosan is hajlandó arra, hogy nem kért style beállításokat szúrjon be a jelölésbe. Miután létrehoztam a <table> korrektúrát, általában visszatérek a Tervezőhöz a webes vezérlők hozzáadásához és a tulajdonságaik beállításához. Előre meghatározott oszlopokkal és sorokkal rendelkező táblák létrehozásakor inkább statikus HTML-t használok, mint a Table Web vezérlőt , mert a Táblázat web vezérlőelemben elhelyezett webvezérlők csak a FindControl("controlID") mintával érhetők el. Azonban a Táblázat webes vezérlőit használom dinamikus méretű táblákhoz (amelyek sorai vagy oszlopai adatbázison vagy felhasználó által megadott feltételeken alapulnak), mivel a Table Web vezérlő programozott módon is létrehozható.
Adja meg a következő jelölést a <asp:Panel> Panel InsertingInterface címkéi között:
<table class="DataWebControlStyle" cellspacing="0">
<tr class="BatchInsertHeaderRow">
<td class="BatchInsertLabel">Supplier:</td>
<td></td>
<td class="BatchInsertLabel">Category:</td>
<td></td>
</tr>
<tr class="BatchInsertRow">
<td class="BatchInsertLabel">Product:</td>
<td></td>
<td class="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<tr class="BatchInsertAlternatingRow">
<td class="BatchInsertLabel">Product:</td>
<td></td>
<td class="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<tr class="BatchInsertRow">
<td class="BatchInsertLabel">Product:</td>
<td></td>
<td class="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<tr class="BatchInsertAlternatingRow">
<td class="BatchInsertLabel">Product:</td>
<td></td>
<td class="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<tr class="BatchInsertRow">
<td class="BatchInsertLabel">Product:</td>
<td></td>
<td class="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<tr class="BatchInsertFooterRow">
<td colspan="4">
</td>
</tr>
</table>
Ez a <table> korrektúra még nem tartalmaz webes vezérlőket, ezeket azonnal hozzáadjuk. Vegye figyelembe, hogy minden <tr> elem tartalmaz egy adott CSS-osztálybeállítást: BatchInsertHeaderRow a fejlécsorhoz, ahová a beszállító és a kategória legördülő listái kerülnek; BatchInsertFooterRow az élőlábsorhoz, ahová a Termékek hozzáadása a Szállításból és a Mégse gombok kerülnek; valamint BatchInsertRow és BatchInsertAlternatingRow váltakozó értékek a sorokhoz, amelyek a termék- és egységár TextBox vezérlőket tartalmazzák. Létrehoztam a megfelelő CSS-osztályokat a Styles.css fájlban, hogy a beszúrási felület megjelenése hasonló legyen a GridView és a DetailsView vezérlőkhöz, amelyeket az oktatóanyagok során használtunk. Ezek a CSS-osztályok alább láthatók.
/*** Styles for ~/BatchData/BatchInsert.aspx tutorial ***/
.BatchInsertLabel
{
font-weight: bold;
text-align: right;
}
.BatchInsertHeaderRow td
{
color: White;
background-color: #900;
padding: 11px;
}
.BatchInsertFooterRow td
{
text-align: center;
padding-top: 5px;
}
.BatchInsertRow
{
}
.BatchInsertAlternatingRow
{
background-color: #fcc;
}
A jelölés beírásával térjen vissza a Tervezési nézethez. Ennek <table> négyoszlopos, hétsoros táblázatként kell megjelennie a Tervezőben, ahogyan azt a 6. ábra szemlélteti.
6. ábra: A beszúrási felület négyoszlopos, Seven-Row táblázatból áll (ide kattintva megtekintheti a teljes méretű képet)
Most már készen állunk a webes vezérlők beszúrására a beszúrási felületre. Húzzon két legördülő listát az eszközkészletből a táblázat megfelelő celláiba, egyet a szállítónak, egyet pedig a kategóriának.
Állítsa be a szállító DropDownList ID tulajdonságát Suppliers értékre, és kösse hozzá egy új ObjectDataSource SuppliersDataSource nevű objektumot. Konfigurálja az új ObjectDataSource-t, hogy lekérje az adatokat az SuppliersBLL osztály GetSuppliers metódusából, és állítsa az UPDATE lap legördülő listáját a (Nincs) értékre. A varázsló befejezéséhez kattintson a Befejezés gombra.
7. ábra: Az ObjectDataSource konfigurálása az SuppliersBLL osztály GetSuppliers metódusának használatára (ide kattintva megtekintheti a teljes méretű képet)
A Suppliers legördülő lista jelenítse meg az CompanyName adatmezőt, és az SupplierID adatmezőt használja értékként annak ListItem kapcsán.
8. ábra: Az adatmező megjelenítése CompanyName és értékként való használata SupplierID (kattintson ide a teljes méretű kép megtekintéséhez)
Nevezze el a második DropDownListet Categories , és kösse hozzá egy új ObjectDataSource nevű CategoriesDataSourceobjektumhoz. Konfigurálja az CategoriesDataSource ObjectDataSource-t az CategoriesBLL osztály s GetCategories metódusának használatára; állítsa az UPDATE és a DELETE lap legördülő listáit a (Nincs) értékre, majd kattintson a Befejezés gombra a varázsló befejezéséhez. Végül a DropDownList megjelenítse az CategoryName adatmezőt, és használja az CategoryID értéket értékként.
Miután ezt a két legördülő listát hozzáadta és a megfelelően konfigurált ObjectDataSourceshoz kötötte, a képernyőnek a 9. ábrához hasonlóan kell kinéznie.
9. ábra: A fejlécsor most tartalmazza a és Suppliers a Categories legördülő listákat (kattintson ide a teljes méretű kép megtekintéséhez)
Most létre kell hoznunk a Szövegdobozokat, hogy összegyűjtsük az egyes új termékek nevét és árát. Húzzon egy TextBox-vezérlőt az eszközkészletből a Tervezőbe az öt terméknév és ársor mindegyikéhez. Állítsa be a ID Szövegdobozok tulajdonságait a ProductName1, UnitPrice1, ProductName2, UnitPrice2, ProductName3, UnitPrice3, stb. értékekre.
Adjon hozzá egy CompareValidatort az egységár szövegmezői után, és állítsa a ControlToValidate tulajdonságot a megfelelőre ID. Állítsa be a Operator tulajdonságot GreaterThanEqual értékre, a ValueToCompare értéket 0-ra, és a Type tulajdonságot Currency értékre. Ezek a beállítások arra utasítják a CompareValidatort, hogy győződjön meg arról, hogy a megadott ár egy érvényes pénznemérték, amely nagyobb vagy egyenlő nullánál. Állítsa a Text tulajdonságot *értékre, az ErrorMessage árnak pedig nullánál nagyobbnak vagy egyenlőnek kell lennie. Emellett hagyja ki a pénznemszimbólumokat.
Megjegyzés:
A beszúrási felület nem tartalmaz RequiredFieldValidator vezérlőket, annak ellenére, hogy az ProductName adatbázistábla Products mezője nem engedélyezi a NULL értékeket. Ennek az az oka, hogy a felhasználó legfeljebb öt terméket szeretne megadni. Ha például a felhasználónak meg kellene adnia az első három sor terméknevét és egységárát, az utolsó két sort üresen hagyva, akkor csak három új terméket adnánk hozzá a rendszerhez. Mivel ProductName azonban szükség van rá, programozott módon kell ellenőriznünk, hogy ha egységárat adunk meg, akkor a megfelelő terméknév-érték van megadva. Ezt az ellenőrzést a 4. lépésben fogjuk kezelni.
A felhasználó bemenetének ellenőrzésekor a CompareValidator érvénytelen adatokat jelent, ha az érték pénznemszimbólumot tartalmaz. Adjon hozzá egy $-t az egységár szövegmezői elé, hogy vizuális jelzésként szolgáljon, amely arra utasítja a felhasználót, hogy hagyja ki a pénznemszimbólumot az ár megadásakor.
Végül adjon hozzá egy ValidationSummary vezérlőt a InsertingInterface panelen belül, állítsa be a ShowMessageBox tulajdonságát True-re és a ShowSummary tulajdonságát False-re. Ezekkel a beállításokkal, ha a felhasználó érvénytelen egységárértéket ad meg, csillag jelenik meg a megsértő TextBox-vezérlők mellett, és az ValidationSummary egy ügyféloldali üzenetmezőt jelenít meg, amely a korábban megadott hibaüzenetet jeleníti meg.
Ekkor a képernyőnek a 10. ábrához hasonlóan kell kinéznie.
10. ábra: A beszúrási felület mostantól tartalmazza a termékek neveihez és áraihoz tartozó szövegdobozokat (kattintson ide a teljes méretű kép megtekintéséhez)
Ezután hozzá kell adnunk a Termékek hozzáadása a Szállításból és a Mégse gombot az élőláb sorához. Húzzon két gombvezérlőt az eszközkészletből a beszúrási felület láblécébe, majd állítsa be az első gomb tulajdonságait ID és AddProducts -ra, a második gomb tulajdonságait pedig CancelButton -ra a "Termékek hozzáadása a szállításból" és a "Mégse" beállításhoz. Emellett állítsa be a CancelButton vezérlőelem CausesValidation tulajdonságát false értékre.
Végül hozzá kell adnunk egy címke webvezérlőt, amely megjeleníti a két felület állapotüzeneteit. Ha például egy felhasználó sikeresen hozzáad egy új termékszállítmányt, vissza szeretnénk térni a megjelenítési felületre, és megerősítő üzenetet szeretnénk megjeleníteni. Ha azonban a felhasználó egy új termék árát adja meg, de nem adja meg a termék nevét, figyelmeztető üzenetet kell jelenítenünk, mivel a ProductName mezőre szükség van. Mivel mindkét felület megjelenítéséhez szükségünk van erre az üzenetre, helyezze az oldal tetejére a Paneleken kívül.
Húzza a Címke web vezérlőelemet az Eszközkészletből a Tervező lapjának tetejére. Állítsa a ID tulajdonságot a következőre StatusLabel, törölje a Text tulajdonságot, és állítsa a VisibleEnableViewState tulajdonságot a következőre False: Ahogy a korábbi oktatóanyagokban láttuk, a EnableViewState tulajdonság False beállításával programozott módon módosíthatjuk a Címke tulajdonságértékeit, és automatikusan visszaállíthatjuk őket az alapértelmezett értékre a későbbi visszavételkor. Ez leegyszerűsíti azt a kódot, amely egy állapotüzenetet jelenít meg a későbbi visszavétel során eltűnő felhasználói műveletre válaszul. Végül állítsa a StatusLabel vezérlő tulajdonságát CssClass Figyelmeztetés értékre, amely egy olyan CSS-osztály Styles.css neve, amely nagy, dőlt, félkövér, piros betűtípussal jeleníti meg a szöveget.
A 11. ábrán a Visual Studio Designer látható a címke hozzáadása és konfigurálása után.
11. ábra: Helyezze a vezérlőt StatusLabel a két panel vezérlője fölé (kattintson ide a teljes méretű kép megtekintéséhez)
3. lépés: Váltás a megjelenítési és beszúrási felületek között
Ezen a ponton befejeztük a megjelenítési és beszúrási felületek korrektúráit, de továbbra is két feladattal rendelkezünk:
- Váltás a kijelző és a beszúrási felületek között
- A szállítmányban lévő termékek hozzáadása az adatbázishoz
A megjelenítési felület jelenleg látható, de a beszúrási felület rejtett. Ennek az az oka, hogy a DisplayInterface Panel s Visible tulajdonságának értéke az alapértelmezett érték True, míg a InsertingInterface Panel s Visible tulajdonsága False. A két interfész közötti váltáshoz egyszerűen ki kell váltanunk az egyes vezérlők tulajdonságértékeit Visible .
A termékszállítmány feldolgozása gombra kattintva a megjelenítési felületről a beszúrási felületre szeretnénk lépni. Ezért hozzon létre egy eseménykezelőt ehhez a Gomb eseményhez Click , amely a következő kódot tartalmazza:
Protected Sub ProcessShipment_Click(sender As Object, e As EventArgs) _
Handles ProcessShipment.Click
DisplayInterface.Visible = False
InsertingInterface.Visible = True
End Sub
Ez a kód egyszerűen elrejti a panelt DisplayInterface , és megjeleníti a panelt InsertingInterface .
Ezután hozza létre a vezérlők eseménykezelőit a szállítmányból történő termékhozzáadáshoz és a Mégse gombhoz a beszúrási felületen. Ha ezekre a gombokra kattint, vissza kell térni a megjelenítési felületre. Hozzon létre Click eseménykezelőket mindkét gombvezérlőhöz, hogy meghívják a ReturnToDisplayInterface metódust – ezt a metódust mindjárt hozzáadjuk. A InsertingInterface panel elrejtése és a DisplayInterface panel megjelenítése mellett a ReturnToDisplayInterface metódusnak helyre kell állítania a webes vezérlőket az előszerkesztési állapotukba. Ez magában foglalja a DropDownLists SelectedIndex tulajdonságok 0 értékre állítását és a Text TextBox-vezérlők tulajdonságainak törlését.
Megjegyzés:
Gondolja át, mi történhet, ha nem ad vissza vezérlőket az előszerkesztési állapotba, mielőtt visszatérne a megjelenítési felületre. Előfordulhat, hogy a felhasználó a Termékszállítás feldolgozása gombra kattint, beírja a szállítmányból származó termékeket, majd kattintson a Termékek hozzáadása szállítmányból elemre. Ez hozzáadja a termékeket, és visszaadja a felhasználót a megjelenítési felületre. Ezen a ponton előfordulhat, hogy a felhasználó egy másik szállítmányt szeretne hozzáadni. A Termékszállítmány feldolgozása gombra kattintva visszatérnek a beszúrási felületre, de a DropDownList-kijelöléseket és a TextBox-értékeket továbbra is feltölti a program a korábbi értékekkel.
Protected Sub AddProducts_Click(sender As Object, e As EventArgs) _
Handles AddProducts.Click
' TODO: Save the products
' Revert to the display interface
ReturnToDisplayInterface()
End Sub
Protected Sub CancelButton_Click(sender As Object, e As EventArgs) _
Handles CancelButton.Click
' Revert to the display interface
ReturnToDisplayInterface()
End Sub
Const firstControlID As Integer = 1
Const lastControlID As Integer = 5
Private Sub ReturnToDisplayInterface()
' Reset the control values in the inserting interface
Suppliers.SelectedIndex = 0
Categories.SelectedIndex = 0
For i As Integer = firstControlID To lastControlID
CType(InsertingInterface.FindControl _
("ProductName" + i.ToString()), TextBox).Text = String.Empty
CType(InsertingInterface.FindControl _
("UnitPrice" + i.ToString()), TextBox).Text = String.Empty
Next
DisplayInterface.Visible = True
InsertingInterface.Visible = False
End Sub
Mindkét Click eseménykezelő egyszerűen meghívja a ReturnToDisplayInterface metódust, bár a 4. lépésben visszatérünk a Termékek hozzáadása a Szállítás Click eseménykezelőhöz, és kódot adunk hozzá a termékek mentéséhez.
ReturnToDisplayInterface visszaállítja a Suppliers és Categories legördülő listákat az első lehetőségeikre. A két állandó, firstControlID és lastControlID, jelöli a kezdő és záró vezérlőindex értékeit, amelyeket a terméknév és az egységár szövegmezőinek elnevezésére használnak a beszúrási felületen, és a For ciklus határaiban szerepelnek, amely a TextBox-vezérlők Text tulajdonságait visszaállítja egy üres sztringre. Végül a Panelek Visible tulajdonságok alaphelyzetbe állnak, hogy a beszúrási felület rejtve legyen, és megjelenjen a megjelenítési felület.
Szánjon egy kis időt a lap kipróbálására egy böngészőben. A lap első megnyitásakor a megjelenítési felületnek kell megjelennie az 5. ábrán látható módon. Kattintson a Termékszállítás feldolgozása gombra. A lap újratöltődik, és most már látnia kell a beszúrási felületet, ahogyan az a 12. ábrán látható. A „Termékek hozzáadása szállításból” vagy a „Mégse” gombra kattintva visszakerül a megjelenítési felületre.
Megjegyzés:
A beszúrási felület megtekintése közben szánjon rá egy kis időt az egységár mezőkön a CompareValidators tesztelésére. Az ügyféloldali üzenetmező figyelmeztetése akkor jelenik meg, ha a Termékek hozzáadása a Szállításból gombra kattint érvénytelen pénznemértékekkel vagy nullánál kisebb értékkel rendelkező árakkal.
12. ábra: A beszúró felület megjelenik, miután a Folyamat termékszállítmány gombra kattintott (ide kattintva megtekintheti a teljes méretű képet)
4. lépés: A termékek hozzáadása
Az oktatóanyagban már csak az van hátra, hogy a termékeket elmentsük az adatbázisba a Termékek hozzáadása a Szállítás gomb Click eseménykezelőjében. Ezt úgy teheti meg, hogy létrehoz egy ProductsDataTable példányt, és hozzáad egy példányt ProductsRow az egyes megadott terméknevekhez. Miután ezeket ProductsRow hozzáadtuk, hívást indítunk az ProductsBLL osztály UpdateWithTransaction metódusára, és átadjuk a ProductsDataTable. Ne feledje, hogy a UpdateWithTransaction metódus, amely a Adatbázismódosítások tranzakcióba burkolása oktatóanyagban jött létre, továbbítja a ProductsDataTable-t a ProductsTableAdapterUpdateWithTransaction metódusának. Innen elindul egy ADO.NET tranzakció, és a TableAdapter utasítást INSERT ad ki az adatbázisnak a DataTable-ban hozzáadott minden egyes elemhez ProductsRow . Feltételezve, hogy az összes termék hiba nélkül lett hozzáadva, a tranzakció véglegesítése történik, ellenkező esetben vissza lesz állítva.
A Termékek hozzáadása a Szállítás gombhoz eseménykezelő kódjának szintén el kell végeznie egy kis hibaellenőrzést. Mivel a beszúrási felületen nincsenek RequiredFieldValidatorok, a felhasználó megadhat egy termék árát, miközben kihagyja a nevét. Mivel a termék nevének megadása kötelező, ha egy ilyen feltétel megjelenik, értesíteni kell a felhasználót, és nem kell folytatni a beszúrásokat. A teljes Click eseménykezelő kód a következő:
Protected Sub AddProducts_Click(sender As Object, e As EventArgs) _
Handles AddProducts.Click
' Make sure that the UnitPrice CompareValidators report valid data...
If Not Page.IsValid Then Exit Sub
' Add new ProductsRows to a ProductsDataTable...
Dim products As New Northwind.ProductsDataTable()
For i As Integer = firstControlID To lastControlID
' Read in the values for the product name and unit price
Dim productName As String = CType(InsertingInterface.FindControl _
("ProductName" + i.ToString()), TextBox).Text.Trim()
Dim unitPrice As String = CType(InsertingInterface.FindControl _
("UnitPrice" + i.ToString()), TextBox).Text.Trim()
' Ensure that if unitPrice has a value, so does productName
If unitPrice.Length > 0 AndAlso productName.Length = 0 Then
' Display a warning and exit this event handler
StatusLabel.Text = "If you provide a unit price you must also
include the name of the product."
StatusLabel.Visible = True
Exit Sub
End If
' Only add the product if a product name value is provided
If productName.Length > 0 Then
' Add a new ProductsRow to the ProductsDataTable
Dim newProduct As Northwind.ProductsRow = products.NewProductsRow()
' Assign the values from the web page
newProduct.ProductName = productName
newProduct.SupplierID = Convert.ToInt32(Suppliers.SelectedValue)
newProduct.CategoryID = Convert.ToInt32(Categories.SelectedValue)
If unitPrice.Length > 0 Then
newProduct.UnitPrice = Convert.ToDecimal(unitPrice)
End If
' Add any "default" values
newProduct.Discontinued = False
newProduct.UnitsOnOrder = 0
products.AddProductsRow(newProduct)
End If
Next
' If we reach here, see if there were any products added
If products.Count > 0 Then
' Add the new products to the database using a transaction
Dim productsAPI As New ProductsBLL()
productsAPI.UpdateWithTransaction(products)
' Rebind the data to the grid so that the products just added are displayed
ProductsGrid.DataBind()
' Display a confirmation (don't use the Warning CSS class, though)
StatusLabel.CssClass = String.Empty
StatusLabel.Text = String.Format( _
"{0} products from supplier {1} have been " & _
"added and filed under category {2}.", _
products.Count, Suppliers.SelectedItem.Text, Categories.SelectedItem.Text)
StatusLabel.Visible = True
' Revert to the display interface
ReturnToDisplayInterface()
Else
' No products supplied!
StatusLabel.Text =
"No products were added. Please enter the " & _
"product names and unit prices in the textboxes."
StatusLabel.Visible = True
End If
End Sub
Az eseménykezelő azzal kezdődik, hogy a Page.IsValid tulajdonság egy értéket Truead vissza. Ha az eredmény False, akkor az azt jelenti, hogy egy vagy több CompareValidator érvénytelen adatokat jelent; ilyen esetben nem szeretnénk megkísérelni a beírt termékek beszúrását, vagy kivételt fogunk eredményezni, amikor megpróbáljuk hozzárendelni a felhasználó által megadott egységárértéket az ProductsRow s UnitPrice tulajdonsághoz.
Ezután létrejön egy új ProductsDataTable példány (products). Egy For ciklus a terméknév és az egységár TextBox-ok iterálására van használva, és a Text tulajdonságok beolvasásra kerülnek a helyi változókba productName és unitPrice. Ha a felhasználó az egységár értékét adta meg, de a megfelelő terméknévhez nem, akkor a StatusLabel megjelenő üzenet jelenik meg Ha egységárat ad meg, akkor a termék nevét is tartalmaznia kell, és az eseménykezelő kilép.
Ha meg van adva egy terméknév, a rendszer új ProductsRow példányt hoz létre az ProductsDataTable s NewProductsRow metódus használatával. Ez az új ProductsRow példány ProductName tulajdonsága az aktuális terméknév TextBox-ra van beállítva, míg a SupplierID és CategoryID tulajdonságok a legördülőlisták SelectedValue tulajdonságaihoz vannak rendelve a beszúrási felület fejlécében. Ha a felhasználó értéket adott meg a termék árához, az a ProductsRow példány tulajdonságához UnitPrice lesz hozzárendelve; ellenkező esetben a tulajdonság hozzárendelés nélkül marad, ami az adatbázisban értéket eredményez NULLUnitPrice . Végül a Discontinued és UnitsOnOrder tulajdonságok az előre megadott értékekhez False és 0 értékhez lettek hozzárendelve.
Miután a ProductsRow példányhoz hozzárendelik a tulajdonságokat, hozzáadják a ProductsDataTable-hez.
A ciklus befejezésekor For ellenőrizzük, hogy lettek-e hozzáadott termékek. A felhasználó végül is rákattinthatott a Termékek hozzáadása szállítmányból elemre, mielőtt bármilyen terméknevet vagy árat megad. Ha legalább egy termék szerepel a ProductsDataTablefájlban, a rendszer meghívja az ProductsBLL s UpdateWithTransaction osztály metódust. Ezután az adatok visszakerülnek a ProductsGrid GridView-ba, így az újonnan hozzáadott termékek megjelennek a megjelenítési felületen. A StatusLabel úgy frissül, hogy megjelenít egy megerősítő üzenetet, és a ReturnToDisplayInterface meghívódik, elrejtve a beszúrási felületet és megjelenítve a megjelenítési felületet.
Ha nem adott meg termékeket, a beszúrási felület továbbra is megjelenik, de a "Nincsenek hozzáadott termékek" üzenet jelenik meg. A megjelenő szövegmezőkben adja meg a termékneveket és az egységárakat.
A 13., 14. és 15. ábra a beszúrási és megjelenítési felületeket jeleníti meg működés közben. A 13. ábrán a felhasználó megadott egy egységárértéket a megfelelő terméknév nélkül. A 14. ábrán három új termék sikeres hozzáadása után látható a megjelenítési felület, míg a 15. ábrán két újonnan hozzáadott termék látható a GridView-ban (a harmadik az előző oldalon található).
13. ábra: Terméknév megadása kötelező egységár megadásakor (kattintson ide a teljes méretű kép megtekintéséhez)
14. ábra: Három új zöldség került hozzáadásra Mayumi szállítmányaihoz (Kattintson ide a teljes méretű kép megtekintéséhez)
15. ábra: Az új termékek a GridView utolsó lapján találhatók (kattintson ide a teljes méretű kép megtekintéséhez)
Megjegyzés:
Az oktatóanyagban használt kötegbeszúrási logika a tranzakció hatókörébe csomagolja a beszúrásokat. Ennek ellenőrzéséhez szándékosan vezessen be egy adatbázisszintű hibát. Például, ahelyett, hogy az új ProductsRow példány CategoryID tulajdonságát a legördülő lista Categories kijelölt értékéhez rendeli, rendelje egy olyan értékhez, mint a i * 5. Itt i található a hurokindexelő, amelynek értékei 1 és 5 között vannak. Ezért ha két vagy több terméket ad hozzá a kötegbe, az első termék érvényes CategoryID értékkel (5) fog rendelkezni, de a későbbi termékek olyan értékekkel fognak rendelkezni CategoryID , amelyek nem egyeznek CategoryID meg a Categories táblázatban szereplő értékekkel. A nettó hatás az, hogy míg az első INSERT sikeres lesz, a későbbiek sikertelenek lesznek egy idegenkulcs-korlátozás megsértésével. Mivel a köteges beszúrás atomi, az első INSERT visszavonásra kerül, így az adatbázis visszaáll az állapotába a kötegbeszúrási folyamat megkezdése előtt.
Összefoglalás
Ezen és az előző két oktatóanyagon keresztül olyan felületeket hoztunk létre, amelyek lehetővé teszik az adatkötegek frissítését, törlését és beszúrását, amelyek mindegyike az adatelérési réteghez hozzáadott tranzakciótámogatást használta a tranzakciós oktatóanyagon belüli burkolóadatbázis-módosításokban . Bizonyos forgatókönyvek esetében az ilyen kötegelt feldolgozás felhasználói felületei jelentősen javítják a végfelhasználói hatékonyságot azáltal, hogy csökkentik a kattintások, a postbackek és a billentyűzetről egér közötti környezeti kapcsolók számát, miközben fenntartják a mögöttes adatok integritását is.
Ez az oktatóanyag befejezi a kötegelt adatokkal végzett munkáról szóló vizsgálatunkat. A következő oktatóanyagok számos speciális adatelérési réteg-forgatókönyvet ismernek meg, beleértve a TableAdapter metódusokban tárolt eljárások használatát, a kapcsolati és parancsszintű beállítások konfigurálását a DAL-ban, a kapcsolati sztringek titkosítását stb.
Boldog programozást!
Tudnivalók a szerzőről
Scott Mitchell, hét ASP/ASP.NET-könyv szerzője és a 4GuysFromRolla.com alapítója, 1998 óta dolgozik a Microsoft webtechnológiáival. Scott független tanácsadóként, edzőként és íróként dolgozik. Legújabb könyve Sams Teach Yourself ASP.NET 2.0 24 óra alatt. Itt érhető el mitchell@4GuysFromRolla.com.
Külön köszönet
Ezt az oktatóanyag-sorozatot sok hasznos véleményező áttekintette. Az oktatóanyag vezető véleményezői Hilton Giesenow és S ren Jacob Lauritsen voltak. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.