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
Ebben az oktatóanyagban egy ASP.NET adat-webvezérlő beszúrási, frissítési vagy törlési művelete előtt, alatt és után előforduló eseményeket fogjuk megvizsgálni. Azt is látni fogjuk, hogyan szabhatja testre a szerkesztőfelületet úgy, hogy csak a termékmezők egy részhalmazát frissítse.
Bevezetés
A GridView, a DetailsView vagy a FormView vezérlők beépített beszúrási, szerkesztési vagy törlési funkcióinak használatakor számos lépés történik, amikor a végfelhasználó befejezi egy új rekord hozzáadásának vagy egy meglévő rekord frissítésének vagy törlésének folyamatát. Ahogy az előző oktatóanyagban is említettük, amikor a GridView-ban szerkesztenek egy sort, a Szerkesztés gombot a Frissítés és a Mégse gomb váltja fel, a BoundFields pedig Szövegmezőkké változik. Miután a végfelhasználó frissítette az adatokat, és a Frissítés gombra kattintott, a rendszer a következő lépéseket hajtja végre a visszavételkor:
- A GridView feltölti az ObjectDataSource objektumait
UpdateParametersa szerkesztett rekord egyedi azonosító mezőivel (aDataKeyNamestulajdonságon keresztül), valamint a felhasználó által megadott értékekkel - A GridView meghívja az ObjectDataSource metódusát
Update(), amely viszont meghívja a megfelelő metódust a mögöttes objektumban (ProductsDAL.UpdateProductaz előző oktatóanyagban) - A mögöttes adatok, amelyek most már tartalmazzák a frissített módosításokat, a GridView-ba kerülnek
A lépések sorozata során számos esemény aktiválódik, ami lehetővé teszi, hogy eseménykezelőket hozzunk létre, hogy szükség esetén egyéni logikát adjunk hozzá. Például az 1. lépés előtt a GridView eseménye RowUpdating aktiválódik. Ezen a ponton visszavonhatjuk a frissítési kérést, ha valamilyen érvényesítési hiba történt.
Update() A metódus meghívásakor az ObjectDataSource eseménye Updating aktiválódik, és lehetővé teszi bármely érték hozzáadását vagy testreszabásátUpdateParameters. Miután az ObjectDataSource mögöttes objektum metódusa végrehajtotta a végrehajtást, az ObjectDataSource eseménye Updated megjelenik. Az esemény eseménykezelője Updated megvizsgálhatja a frissítési művelet részleteit, például hogy hány sort érintett, és hogy történt-e kivétel. Végül a 2. lépés után a GridView eseménye RowUpdated aktiválódik; az esemény eseménykezelője további információkat vizsgálhat meg az imént végrehajtott frissítési műveletről.
Az 1. ábra az események és lépések sorozatát mutatja be a GridView frissítésekor. Az 1. ábrán szereplő eseményminta nem egyedi a GridView-val való frissítéshez. A GridView, a DetailsView vagy a FormView adatainak beszúrása, frissítése vagy törlése ugyanazokat az elő- és utáni események sorozatát jelenti mind az adat-webvezérlő, mind az ObjectDataSource esetében.
1. ábra: Események előtti és utáni tűzesetek sorozata, amikor adatokat frissít egy GridView-ban (kattintson ide a teljes méretű kép megtekintéséhez)
Ebben az oktatóanyagban ezeket az eseményeket használva bővítjük a ASP.NET adat-webvezérlők beépített beszúrási, frissítési és törlési képességeit. Azt is látni fogjuk, hogyan szabhatja testre a szerkesztőfelületet úgy, hogy csak a termékmezők egy részhalmazát frissítse.
1. lépés: TermékProductNameésUnitPricemezők frissítése
Az előző oktatóanyag szerkesztőfelületeiben minden olyan termékmezőt fel kellett venni, amely nem írásvédett. Ha el szeretnénk távolítani egy mezőt a GridView-ból - mondjuk QuantityPerUnit - az adatok frissítésekor az adat-webvezérlő nem állítaná be az ObjectDataSource QuantityPerUnitUpdateParameters értékét. Az ObjectDataSource ezután átad egy null értéket az UpdateProduct Üzleti logikai réteg (BLL) metódusnak, amely a szerkesztett adatbázisrekord oszlopát értékre QuantityPerUnit módosítjaNULL. Hasonlóképpen, ha egy kötelező mezőt( például ProductName) eltávolít a szerkesztőfelületről, a frissítés "ProductName oszlop nem engedélyezi a null értéket" kivétellel meghiúsul. Ennek a viselkedésnek az az oka, hogy az ObjectDataSource úgy lett konfigurálva, hogy meghívja az ProductsBLL osztály metódusát UpdateProduct , ami minden termékmezőhöz várt egy bemeneti paramétert. Ezért az ObjectDataSource UpdateParameters gyűjteménye tartalmazott egy paramétert a metódus egyes bemeneti paramétereihez.
Ha olyan adat webes vezérlőt szeretnénk biztosítani, amely lehetővé teszi a végfelhasználó számára, hogy csak a mezők egy részhalmazát frissítse, akkor vagy programozott módon kell beállítanunk a hiányzó UpdateParameters értékeket az ObjectDataSource eseménykezelőjében Updating , vagy létre kell hoznunk és meghívnunk egy BLL-metódust, amely csak a mezők egy részhalmazát várja. Vizsgáljuk meg ezt az utóbbi megközelítést.
Pontosabban hozzunk létre egy lapot, amely csak a szerkeszthető GridView mezőit ProductNameUnitPrice jeleníti meg. Ez a GridView szerkesztőfelülete csak a két megjelenített mező frissítését teszi lehetővé a felhasználó számára. ProductNameUnitPrice Mivel ez a szerkesztőfelület csak egy termék mezőinek egy részhalmazát biztosítja, vagy létre kell hoznunk egy ObjectDataSource-t, amely a meglévő BLL metódusát UpdateProduct használja, és a hiányzó termékmező-értékeket programozott módon állítja be az eseménykezelőben Updating , vagy létre kell hoznunk egy új BLL-metódust, amely csak a GridView-ban definiált mezők részhalmazát várja. Ebben az oktatóanyagban használjuk az utóbbi lehetőséget, és hozzuk létre a UpdateProduct metódus túlterhelését, amely mindössze három bemeneti paramétert vesz fel: productName, unitPriceés productID:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, decimal? unitPrice, int productID)
{
Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
if (products.Count == 0)
// no matching record found, return false
return false;
Northwind.ProductsRow product = products[0];
product.ProductName = productName;
if (unitPrice == null) product.SetUnitPriceNull();
else product.UnitPrice = unitPrice.Value;
// Update the product record
int rowsAffected = Adapter.Update(product);
// Return true if precisely one row was updated, otherwise false
return rowsAffected == 1;
}
Az eredeti UpdateProduct módszerhez hasonlóan ez a túlterhelés azzal kezdődik, hogy ellenőrzi, hogy van-e termék az adatbázisban a megadott ProductID. Ha nem, akkor az eredmény falseazt jelzi, hogy a termékinformáció frissítésére irányuló kérés nem sikerült. Ellenkező esetben ennek megfelelően frissíti a meglévő termékrekord ProductName és UnitPrice mezőit, és a frissítést a Update() példányt átadva véglegesíti a TableAdapter ProductsRow metódusának meghívásával.
Az ProductsBLL osztály hozzáadásával készen állunk az egyszerűsített GridView felület létrehozására. Nyissa meg a DataModificationEvents.aspx mappában található EditInsertDelete elemet, és vegyen fel egy GridView-t a lapra. Hozzon létre egy új ObjectDataSource-t, és konfigurálja úgy, hogy az ProductsBLL osztályt használja a Select() metódusként GetProducts-ra és a Update() metódusként annak a UpdateProduct túlterhelésének megfelelően, amely csak a productName, unitPrice és productID bemeneti paramétereket veszi fel. A 2. ábrán az Adatforrás létrehozása varázsló látható, amikor az ObjectDataSource metódusát Update() az ProductsBLL osztály új UpdateProduct metódusterheltségéhez megfelelteti.
2. ábra: Az ObjectDataSource metódusának leképezése Update() az új UpdateProduct túlterhelésre (kattintson ide a teljes méretű kép megtekintéséhez)
Mivel a példánkban először csak az adatok szerkesztésére lesz szükség, de nem kell rekordokat beszúrni vagy törölni, szánjon egy kis időt arra, hogy explicit módon jelezze, hogy az ObjectDataSource Insert() és Delete() metódusai nem képezhetők le az osztály egyik metódusára sem ProductsBLL . Ehhez lépjen az INSERT és a DELETE fülre, és válassza a (Nincs) lehetőséget a legördülő listából.
3. ábra: Válassza a (Nincs) lehetőséget a BESZÚRÁS és TÖRLÉS lapok Drop-Down listájából (a teljes méretű kép megtekintéséhez kattintson ide)
A varázsló befejezése után jelölje be a Szerkesztés engedélyezése jelölőnégyzetet a GridView intelligens címkéjén.
Az Adatforrás létrehozása varázsló befejezésével és a GridView-hoz való kötéssel a Visual Studio létrehozta mindkét vezérlő deklaratív szintaxisát. Nyissa meg a Forrás nézetet az ObjectDataSource deklaratív korrektúrája vizsgálatához, amely az alábbiakban látható:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Mivel nincsenek leképezések az ObjectDataSource Insert() és Delete() metódusaihoz, nincsenek InsertParameters vagy DeleteParameters szakaszok. Továbbá, mivel a metódus a Update() metódus túlterheléséhez UpdateProduct van hozzárendelve, amely csak három bemeneti paramétert fogad el, a UpdateParameters szakasznak mindössze három Parameter példánya van.
Vegye figyelembe, hogy az ObjectDataSource tulajdonsága OldValuesParameterFormatString a következőre original_{0}van állítva: . Ezt a tulajdonságot a Visual Studio automatikusan állítja be az Adatforrás konfigurálása varázsló használatakor. Mivel azonban a BLL-metódusok nem várják az eredeti ProductID érték átadását, távolítsa el ezt a tulajdonság-hozzárendelést teljesen az ObjectDataSource deklaratív szintaxisából.
Megjegyzés:
Ha egyszerűen törli a tulajdonság értékét a OldValuesParameterFormatString Tervező nézetben a Tulajdonságok ablakból, a tulajdonság továbbra is létezik a deklaratív szintaxisban, de egy üres sztringre lesz beállítva. Távolítsa el a tulajdonságot teljesen a deklaratív szintaxisból, vagy a Tulajdonságok ablakból állítsa be az alapértelmezett értéket. {0}
Bár az ObjectDataSource csak a termék nevére, árára és azonosítójára vonatkozik UpdateParameters , a Visual Studio hozzáadott egy BoundField vagy CheckBoxField mezőt a GridView-ban az egyes termékek mezőihez.
4. ábra: A GridView egy BoundField vagy CheckBoxField mezőt tartalmaz a termék mezőihez (ide kattintva megtekintheti a teljes méretű képet)
Amikor a végfelhasználó szerkeszt egy terméket, és a "Frissítés" gombra kattint, a GridView felsorolja azokat a mezőket, amelyek nem írásvédettek. Ezután az ObjectDataSource gyűjteményében lévő megfelelő paraméter értékét a felhasználó által megadott értékre állítja UpdateParameters . Ha nincs megfelelő paraméter, a GridView hozzáad egyet a gyűjteményhez. Ezért, ha a GridView a termék összes mezőjéhez tartozó BoundField-eket és CheckBoxField-eket tartalmaz, az ObjectDataSource végül az összes paramétert felvevő túlterhelt változatot fogja meghívni, annak ellenére, hogy az ObjectDataSource deklaratív jelölése csak három bemeneti paramétert határoz meg (nézze meg az 5. ábrát). Hasonlóképpen, ha a GridView-ban a nem írásvédett termékmezők kombinációja nem felel meg a UpdateProduct túlterhelés bemeneti paramétereinek, akkor a frissítési kísérletnél kivétel fog felmerülni.
5. ábra: A GridView paramétereket ad hozzá az ObjectDataSource gyűjteményéhez UpdateParameters (ide kattintva megtekintheti a teljes méretű képet)
Annak érdekében, hogy az ObjectDataSource meghívja a UpdateProduct túlterhelést, amely csak a termék nevét, árát és azonosítóját veszi fel, korlátoznunk kell a GridView-t úgy, hogy szerkeszthetők legyenek a mezők csak a ProductName és UnitPrice számára. Ez a többi BoundFields és CheckBoxFields eltávolításával, a többi mező ReadOnly tulajdonságának truebeállításával vagy a kettő valamilyen kombinációjával valósítható meg. Ebben az oktatóanyagban egyszerűen távolítsa el az összes GridView-mezőt, kivéve a ProductName és UnitPrice BoundFields mezőket, amely után a GridView deklaratív jelölési nyelve a következőképpen fog kinézni:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
Annak ellenére, hogy a UpdateProduct túlterhelés három bemeneti paramétert vár, csak két BoundField van a GridView-ban. Ennek az az oka, hogy a productID bemeneti paraméter egy elsődleges kulcsérték, és a szerkesztett sor tulajdonságának DataKeyNames értékén keresztül kerül átadásra.
A GridView a UpdateProduct túlterheléssel lehetővé teszi a felhasználónak, hogy csak a termék nevét és árát szerkessze, miközben a többi termékmező nem vész el.
6. ábra: A felület lehetővé teszi, hogy csak a termék nevét és árát szerkessze (kattintson ide a teljes méretű kép megtekintéséhez)
Megjegyzés:
Az előző oktatóanyagban leírtaknak megfelelően létfontosságú, hogy a GridView nézetállapota engedélyezve legyen (az alapértelmezett viselkedés). Ha Ön a GridView EnableViewState tulajdonságát false beállítja, fennáll annak a kockázata, hogy párhuzamos felhasználók véletlenül rekordokat törölnek vagy szerkesztenek.
UnitPriceA formázás javítása
Bár a 6. ábrán látható GridView-példa működik, a UnitPrice mező egyáltalán nem formázott, ezért olyan árkijelzést eredményez, amely nem tartalmaz pénznemszimbólumokat, és négy tizedesjegyet tartalmaz. A nem szerkeszthető sorok pénznemformátumának alkalmazásához egyszerűen állítsa be a UnitPrice BoundField DataFormatString tulajdonságát {0:c}-re és a HtmlEncode tulajdonságot false-re.
7. ábra: Állítsa be a UnitPrice az DataFormatString és a HtmlEncode tulajdonságait ennek megfelelően (Kattintson ide a teljes méretű kép megtekintéséhez)
Ezzel a módosítással a nem szerkeszthető sorok pénznemként formázják az árat; a szerkesztett sor azonban továbbra is megjeleníti az értéket pénznemszimbólum és négy tizedesjegy nélkül.
8. ábra: A nem szerkeszthető sorok mostantól pénznemértékekként vannak formázva (ide kattintva megtekintheti a teljes méretű képet)
A tulajdonságban megadott formázási DataFormatString utasítások alkalmazhatók a szerkesztőfelületre a BoundField ApplyFormatInEditMode tulajdonságának true beállításával (az alapértelmezett érték false). Szánjon egy kis időt arra, hogy beállítsa ezt a tulajdonságot true.
9. ábra: Állítsa be a UnitPrice BoundField tulajdonságát ApplyFormatInEditModetrue (kattintson ide a teljes méretű kép megtekintéséhez)
Ezzel a módosítással a UnitPrice szerkesztett sorban megjelenített érték pénznemként is formázva lesz.
10. ábra: A szerkesztett sor UnitPrice értéke mostantól pénznemként van formázva (ide kattintva megtekintheti a teljes méretű képet)
Egy termék frissítése azonban a szövegmezőben lévő pénznemszimbólummal (például $19.00) FormatException. Amikor a GridView megpróbálja hozzárendelni a felhasználó által megadott értékeket az ObjectDataSource gyűjteményéhez UpdateParameters , nem tudja konvertálni a UnitPrice "$19.00" sztringet a decimal paraméter által megkövetelt értékké (lásd a 11. ábrát). Ennek orvoslásához létrehozhatunk egy eseménykezelőt a GridView RowUpdating eseményéhez, és feldolgozhatjuk a felhasználó által megadott UnitPrice adatot pénznemformátumúként decimal.
A GridView eseménye RowUpdating második paramétereként egy GridViewUpdateEventArgs típusú objektumot fogad el, amely egy szótárt tartalmaz NewValues annak egyik tulajdonságaként, amely a felhasználó által megadott értékeket tartalmazza, és készen áll az ObjectDataSource UpdateParameters gyűjteményéhez való hozzárendelésre. Felülírhatjuk a UnitPrice gyűjtemény meglévő NewValues értékét egy decimális értékkel, amelyet a pénznemformátum használatával elemeztünk a RowUpdating eseménykezelőben a következő kódsorokkal:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
e.NewValues["UnitPrice"] =
decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
Ha a felhasználó megadott egy UnitPrice értéket (például "19,00 USD"), a rendszer felülírja ezt az értéket a Decimal.Parse által kiszámított decimális értékkel, és pénznemként elemzi az értéket. Ez megfelelően elemzi a decimális értéket bármilyen pénznemszimbólum, vessző, tizedespont stb. esetén, és a System.Globalization névtérBen a NumberStyles enumerálást használja.
A 11. ábra a felhasználó által megadott UnitPricepénznemszimbólumok által okozott problémát mutatja be, valamint azt, hogy a GridView eseménykezelője RowUpdating hogyan használható az ilyen bemenet megfelelő elemzéséhez.
11. ábra: A szerkesztett sor UnitPrice értéke mostantól pénznemként van formázva (ide kattintva megtekintheti a teljes méretű képet)
2. lépés: TiltásNULL UnitPrices
Bár az adatbázis úgy van konfigurálva, hogy engedélyezze NULL a Products tábla UnitPrice oszlopában lévő értékeket, előfordulhat, hogy az adott oldalt látogató felhasználók nem adhatnak meg NULLUnitPrice értéket. Vagyis ha egy felhasználó nem tud értéket megadni UnitPrice egy terméksor szerkesztésekor, ahelyett, hogy az eredményeket az adatbázisba mentené, egy üzenetet jelenítünk meg, amely tájékoztatja a felhasználót, hogy ezen a lapon minden szerkesztett terméknek meg kell adnia egy árat.
A GridViewUpdateEventArgs GridView eseménykezelőjének RowUpdating átadott objektum olyan tulajdonságot Cancel tartalmaz, amely ha be van állítva true, leállítja a frissítési folyamatot. Bővítsük ki az RowUpdating eseménykezelőt úgy, hogy beállítja a e.Cancel-t true-re, és megjelenít egy üzenetet, amely elmagyarázza, hogy miért, ha a UnitPrice értéke a NewValues gyűjteményben null.
Első lépésként adjon hozzá egy Címke web vezérlőelemet a névvel ellátott MustProvideUnitPriceMessagelaphoz. Ez a Címke vezérlőelem akkor jelenik meg, ha a felhasználó nem tud értéket megadni egy UnitPrice termék frissítésekor. Állítsa a Címke tulajdonságát Text a következőre: "Meg kell adnia a termék árát". Létrehoztam egy új CSS-osztályt Styles.css is a következő definícióval elnevezve Warning :
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
Végül állítsa a Címke CssClass tulajdonságát Warning-re. Ezen a ponton a Tervezőnek a figyelmeztető üzenetet piros, félkövér, dőlt, extra nagy betűméretben kell megjelenítenie a GridView fölött, ahogy a 12. ábrán látható.
12. ábra: Felirat lett hozzáadva a GridView fölött (kattintson ide a teljes méretű kép megtekintéséhez)
Alapértelmezés szerint ennek a címkének rejtettnek kell lennie, ezért állítsa be a tulajdonságát Visiblefalse az Page_Load eseménykezelőben:
protected void Page_Load(object sender, EventArgs e)
{
MustProvideUnitPriceMessage.Visible = false;
}
Ha a felhasználó a termék megadása UnitPricenélkül próbál frissíteni egy terméket, a frissítést le szeretnénk mondani, és megjelenítjük a figyelmeztető címkét. Bővítse a GridView eseménykezelőjét RowUpdating az alábbiak szerint:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
{
e.NewValues["UnitPrice"] =
decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
else
{
// Show the Label
MustProvideUnitPriceMessage.Visible = true;
// Cancel the update
e.Cancel = true;
}
}
Ha egy felhasználó ár megadása nélkül próbál menteni egy terméket, a frissítés megszakad, és megjelenik egy hasznos üzenet. Bár az adatbázis (és az üzleti logika) lehetővé teszi a NULLUnitPrice alkalmazását, ez az adott ASP.NET oldal nem.
13. ábra: A felhasználó nem hagyhatja UnitPrice üresen (kattintson ide a teljes méretű kép megtekintéséhez)
Eddig láthattuk, hogyan használhatja a GridView eseményét RowUpdating az ObjectDataSource UpdateParameters gyűjteményéhez hozzárendelt paraméterértékek programozott módosítására, valamint a frissítési folyamat teljes megszakítására. Ezek a fogalmak átvitelre kerülnek a DetailsView és a FormView vezérlőkre, és kiterjednek a beszúrásra és törlésre is.
Ezek a feladatok az ObjectDataSource szintjén is elvégezhetők az eseménykezelőken keresztül annak Inserting, Updatingés Deleting az események számára. Ezek az események a mögöttes objektum társított metódusának meghívása előtt aktiválódnak, és utolsó esélyt biztosítanak a bemeneti paraméterek gyűjteményének módosítására vagy a művelet megszakítására. A három esemény eseménykezelői egy ObjectDataSourceMethodEventArgs típusú objektumot adnak át, amely két érdekes tulajdonsággal rendelkezik:
-
Mégse, amely ha be van
trueállítva, megszakítja a végrehajtott műveletet -
InputParameters, amely a
InsertParameters,UpdateParameters, vagyDeleteParametersgyűjtemény, attól függően, hogy az eseménykezelő azInserting,Updating, vagyDeletingesemény
Ha az ObjectDataSource szintjén szeretné szemléltetni a paraméterértékekkel való munkát, foglaljunk be egy DetailsView-t a lapunkba, amely lehetővé teszi a felhasználók számára, hogy új terméket vegyenek fel. Ez a DetailsView egy felületet biztosít, amellyel gyorsan hozzáadhat egy új terméket az adatbázishoz. Engedélyezze a felhasználónak, hogy csak a ProductName és UnitPrice mezők értékeit adja meg az új termék hozzáadásakor, hogy konzisztens maradjon a felhasználói felület. Alapértelmezés szerint azok az értékek, amelyek nem szerepelnek a DetailsView beszúrási felületén, adatbázis-értékre NULL lesznek állítva. Az ObjectDataSource eseményével Inserting azonban különböző alapértelmezett értékeket szúrhatunk be, amint azt hamarosan látni fogjuk.
3. lépés: Új termékek hozzáadására szolgáló felület biztosítása
Húzzon egy DetailsView-t az eszközkészletből a Tervezőre a GridView fölött, törölje annak Height és Width tulajdonságait, és kötse össze a lapon már meglévő ObjectDataSource-zal. Ezzel hozzáad egy BoundField vagy CheckBoxField mezőt a termék minden mezőjéhez. Mivel ezt a DetailsView-t szeretnénk használni új termékek hozzáadásához, az intelligens címkéről ellenőrizni kell a Beszúrás engedélyezése lehetőséget; Azonban nincs ilyen lehetőség, mert az ObjectDataSource metódusa Insert() nincs leképezve az ProductsBLL osztály egyik metódusára (ne feledje, hogy ezt a leképezést (Nincs) állítottuk be az adatforrás konfigurálásakor, lásd a 3. ábrát).
Az ObjectDataSource konfigurálásához válassza az Adatforrás konfigurálása hivatkozást az intelligens címkéből, és indítsa el a varázslót. Az első képernyőn módosíthatja az alatta lévő objektumot, amelyhez az ObjectDataSource kötődik; hagyja azt ProductsBLL értéken. A következő képernyő az ObjectDataSource metódusainak a hozzárendeléseit sorolja fel az alapobjektumhoz. Annak ellenére, hogy kifejezetten jeleztük, hogy a Insert() és Delete() metódusokat nem szabad egyetlen metódushoz sem leképezni, ha az INSERT és a DELETE fülre megy, látni fogja, hogy van leképezés. Ennek az az oka, hogy a ProductsBLLAddProduct és DeleteProduct metódusok az DataObjectMethodAttribute attribútumot használják annak jelzésére, hogy ezek az alapértelmezett metódusok a Insert() és a Delete() esetében. Ezért az ObjectDataSource varázsló ezeket választja ki minden alkalommal, amikor futtatja a varázslót, kivéve, ha explicit módon más érték van megadva.
Hagyja a Insert() metódust a AddProduct metódusra mutatva, de állítsa ismét a DELETE fül legördülő listáját a (Nincs) értékre.
14. ábra: Az INSERT lap Drop-Down listájának beállítása metódusra (AddProduct teljes méretű képet)
A DELETE lap Drop-Down listáját állítsa (Nincs) állapotra
15. ábra: A DELETE lap Drop-Down listájának beállítása (Nincs) (Ide kattintva megtekintheti a teljes méretű képet)
A módosítások elvégzése után az ObjectDataSource deklaratív szintaxisa ki lesz bővítve egy InsertParameters gyűjteménnyel, ahogy az alábbiakban látható:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<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>
Újra futtatva a varázslót, vissza lett állítva a OldValuesParameterFormatString tulajdonság. Szánjon egy kis időt a tulajdonság törlésére az alapértelmezett érték ({0}) beállításával vagy a deklaratív szintaxisból való teljes eltávolításával.
Miután az ObjectDataSource beszúrási képességeket biztosít, a DetailsView intelligens címkéje mostantól tartalmazza a Beszúrás engedélyezése jelölőnégyzetet; térjen vissza a Tervezőhöz, és ellenőrizze ezt a beállítást. Ezután csökkentsd le a DetailsView-t, hogy csak két BoundFields - ProductName és UnitPrice - és a CommandField legyen benne. Ekkor a DetailsView deklaratív szintaxisának a következőképpen kell kinéznie:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
A 16. ábrán ez a lap jelenik meg, ha jelenleg egy böngészőben tekinti meg. Mint látható, a DetailsView felsorolja az első termék (Chai) nevét és árát. Azt szeretnénk azonban, hogy egy beszúrási felület, amely lehetővé teszi a felhasználó számára, hogy gyorsan vegyen fel egy új terméket az adatbázisba.
16. ábra: A DetailsView jelenleg Read-Only módban jelenik meg (kattintson ide a teljes méretű kép megtekintéséhez)
Ahhoz, hogy a DetailsView beszúrási módban jelenjen meg, be kell állítanunk a DefaultMode tulajdonságot Inserting értékre. Ez beszúrási módban jeleníti meg a DetailsView-t, amikor először megtekintette, és megtartja azt egy új rekord beszúrása után. Ahogy a 17. ábra mutatja, az ilyen DetailsView gyors felületet biztosít egy új rekord hozzáadásához.
17. ábra: A DetailsView egy felületet biztosít az új termék gyors hozzáadásához (ide kattintva megtekintheti a teljes méretű képet)
Amikor a felhasználó megadja a termék nevét és árát (például az "Acme Water" és az 1.99, mint a 17. ábrán), és a Beszúrás gombra kattint, elindul a postback és a beszúrási munkafolyamat, amely egy új termékrekordot ad hozzá az adatbázishoz. A DetailsView fenntartja a beszúrási felületet, és a GridView automatikusan visszapattan az adatforrásba, hogy az új terméket is belefoglalja a 18. ábrán látható módon.
18. ábra: Az "Acme Water" termék hozzáadva az adatbázishoz
Bár a 18. ábrán a GridView nem jelenik meg, a DetailsView felületből CategoryIDSupplierIDQuantityPerUnithiányzó termékmezők adatbázisértékeket kapnak.NULL Ezt a következő lépések végrehajtásával tekintheti meg:
- Ugrás a Kiszolgálókezelőre a Visual Studióban
- Az
NORTHWND.MDFadatbáziscsomópont bővítése - Kattintson a jobb gombbal az
Productsadatbázistábla csomópontjára - Válassza a Táblaadatok megjelenítése lehetőséget
Ez felsorolja a tábla összes rekordját Products . Ahogy a 19. ábra mutatja, az új termék oszlopai, a ProductID, ProductName és UnitPrice kivételével, NULL értékekkel rendelkeznek.
19. ábra: A DetailsView-ban nem megadott termékmezők hozzárendelt NULL értékek (ide kattintva megtekintheti a teljes méretű képet)
Előfordulhat, hogy egy vagy több oszlop értékétől eltérő NULL alapértelmezett értéket szeretnénk megadni, akár azért, mert NULL nem a legjobb alapértelmezett beállítás, vagy mert maga az adatbázisoszlop nem engedélyezi NULL az s értéket. Ehhez programozott módon állíthatjuk be a DetailsView InputParameters gyűjteményének paramétereinek értékeit. Ez a hozzárendelés elvégezhető a DetailsView eseményének eseménykezelőjében ItemInserting vagy az ObjectDataSource eseményében Inserting . Mivel az adat-webvezérlés szintjén már megvizsgáltuk a pre- és post-level események használatát, most vizsgáljuk meg az ObjectDataSource eseményeit.
4. lépés: Értékek hozzárendelése a CategoryID és SupplierID paraméterekhez
Képzeljük el ebben az oktatóanyagban, hogy az alkalmazásunkban, amikor egy új terméket adunk hozzá ezen a felületen keresztül, akkor a CategoryID és SupplierID értékeket 1-re kell beállítani. Ahogy korábban említettük, az ObjectDataSource rendelkezik egy pár elő- és utószintű eseménysel, amelyek az adatmódosítási folyamat során aktiválódnak. Amikor a Insert() metódusát meghívják, az ObjectDataSource először elindítja a Inserting eseményt, majd meghívja azt a metódust, amelyhez a Insert() metódus van leképezve, és végül elindítja a Inserted eseményt. Az Inserting eseménykezelő egy utolsó lehetőséget biztosít számunkra a bemeneti paraméterek finomhangolására vagy a művelet megszakítására.
Megjegyzés:
Egy valós alkalmazásban valószínűleg engedélyezni szeretné a felhasználónak, hogy megadja a kategóriát és a szállítót, vagy bizonyos feltételek vagy üzleti logika alapján válassza ki ezt az értéket (ahelyett, hogy vakon kiválasztaná az 1-es azonosítót). Ettől függetlenül a példa bemutatja, hogyan állíthatja be programozott módon egy bemeneti paraméter értékét az ObjectDataSource előszintű eseményéből.
Hozzon létre egy eseménykezelőt az ObjectDataSource eseményéhez Inserting . Figyelje meg, hogy az eseménykezelő második bemeneti paramétere egy olyan típusú ObjectDataSourceMethodEventArgsobjektum, amely rendelkezik egy tulajdonságmal a paraméterek gyűjteményéhez (InputParameters) és egy tulajdonsághoz a művelet megszakításához (Cancel).
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
}
Ezen a ponton a InputParameters tulajdonság tartalmazza az ObjectDataSource gyűjteményét InsertParameters a DetailsView-ból hozzárendelt értékekkel. Ezen paraméterek egyikének értékének módosításához egyszerűen használja a következőt: e.InputParameters["paramName"] = value. Ezért az CategoryIDSupplierID 1 értékének beállításához állítsa be az Inserting eseménykezelőt úgy, hogy az a következőképpen nézzen ki:
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
e.InputParameters["CategoryID"] = 1;
e.InputParameters["SupplierID"] = 1;
}
Új termék (például Acme Soda) hozzáadásakor az CategoryID új termék oszlopai és SupplierID oszlopai 1 értékre vannak állítva (lásd a 20. ábrát).
Az új termékek kategóriaazonosítója és szállítóazonosítója értékei most 1-re lettek állítva.
20. ábra: Az új termékek most már 1-es értékre CategoryIDSupplierID vannak állítva (ide kattintva megtekintheti a teljes méretű képet)
Összefoglalás
A szerkesztési, beszúrási és törlési folyamat során az adat webes vezérlője és az ObjectDataSource is számos elő- és utószintű eseményen halad végig. Ebben az oktatóanyagban megvizsgáltuk az előzetes szintű eseményeket, és láttuk, hogyan lehet ezeket használni a bemeneti paraméterek testreszabására vagy az adatmódosítási művelet megszakítására mind az adat-webvezérlőből, mind az ObjectDataSource eseményeiből. A következő oktatóanyagban az eseménykezelők létrehozását és használatát tekintjük át a posztszintű eseményekhez.
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 van. Ő itt elérhető 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 Jackie Goor és Liz Shulok voltak. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.