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 hozhat létre teljes mértékben szerkeszthető DataListet, amelyben az összes elem szerkesztési módban van, és amelynek értékei menthetők a lapon található "Az összes frissítése" gombra kattintva.
Bevezetés
Az előző oktatóanyagban megvizsgáltuk, hogyan hozható létre elemszintű DataList. A szabványos szerkeszthető GridView-hoz hasonlóan a DataList minden eleme tartalmazott egy Szerkesztés gombot, amely kattintás után szerkeszthetővé tenné az elemet. Bár ez az elemszintű szerkesztés jól működik az olyan adatok esetében, amelyek csak alkalmanként frissülnek, bizonyos használati esetek esetén a felhasználónak számos rekordot kell szerkesztenie. Ha egy felhasználónak több tucat rekordot kell szerkesztenie, és a Szerkesztés gombra kell kattintania, végezze el a módosításokat, és kattintson mindegyiknél a Frissítés gombra, a kattintás mennyisége akadályozhatja a termelékenységet. Ilyen helyzetekben jobb megoldás egy teljes mértékben szerkeszthető DataList biztosítása, amelyben az összes elem szerkesztési módban van, és amelynek értékei szerkeszthetők a lapon található Összes frissítése gombra kattintva (lásd az 1. ábrát).
1. ábra: A teljes mértékben szerkeszthető adatlista minden eleme módosítható (ide kattintva megtekintheti a teljes méretű képet)
Ebben az oktatóanyagban azt vizsgáljuk meg, hogyan engedélyezheti a felhasználók számára a szállítók címadatainak frissítését egy teljes mértékben szerkeszthető DataList használatával.
1. lépés: A szerkeszthető felhasználói felület létrehozása a DataList s ItemTemplate-ban
Az előző oktatóanyagban, amelyben egy szabványos, elemszintű szerkeszthető DataListet hoztunk létre, két sablont használtunk:
-
ItemTemplatetartalmazta az írásvédett felhasználói felületet (az egyes termékek nevének és árának megjelenítésére szolgáló címke webes vezérlői). -
EditItemTemplatetartalmazta a szerkesztési mód felhasználói felületét (a két TextBox webvezérlőt).
A DataList tulajdonsága EditItemIndex határozza meg, hogy mely elem DataListItem van megjelenítve a EditItemTemplate segítségével, ha van ilyen. A DataListItem, amelynek ItemIndex értéke megegyezik a DataList EditItemIndex tulajdonságával, különösen a EditItemTemplate segítségével kerül megjelenítésre. Ez a modell akkor működik jól, ha egyszerre csak egy elem szerkeszthető, de teljesen szerkeszthető DataList létrehozásakor szétesik.
Teljes mértékben szerkeszthető DataList esetén azt szeretnénk, hogy az DataListItem adat renderelhető legyen a szerkeszthető felületen. Ennek legegyszerűbb módja a szerkeszthető felület definiálása a ItemTemplate. A szállítók címadatainak módosításához a szerkeszthető felület szövegként tartalmazza a szállító nevét, majd a cím, a város és az ország/régió értékeinek szövegmezőit.
Először nyissa meg a BatchUpdate.aspx lapot, adjon hozzá egy DataList-vezérlőt, és állítsa be a tulajdonságát ID a következőre Suppliers: . A DataList intelligens címkéjéről válassza ki az új ObjectDataSource-vezérlő hozzáadását, amely SuppliersDataSource nevű.
2. ábra: Új ObjectDataSource névvel ellátott SuppliersDataSource objektum létrehozása (ide kattintva megtekintheti a teljes méretű képet)
Konfigurálja az ObjectDataSource-t az adatok lekérésére az SuppliersBLL osztály metódusával GetSuppliers() (lásd a 3. ábrát). Az előző oktatóanyaghoz hasonlóan a szállítói adatok ObjectDataSource-on keresztüli frissítése helyett közvetlenül az üzleti logikai réteggel fogunk dolgozni. Ezért állítsa a legördülő listát (Nincs) a FRISSÍTÉS lapon (lásd a 4. ábrát).
3. ábra: Szállítói adatok lekérése a GetSuppliers() módszerrel (kattintson ide a teljes méretű kép megtekintéséhez)
4. ábra: Állítsa a Drop-Down listát (Nincs) a FRISSÍTÉS lapon (ide kattintva megtekintheti a teljes méretű képet)
A varázsló befejezése után a Visual Studio automatikusan létrehozza a DataList s-eket ItemTemplate , hogy megjelenítse az adatforrás által visszaadott összes adatmezőt egy Címke webvezérlőben. Úgy kell módosítanunk ezt a sablont, hogy az inkább a szerkesztőfelületet nyújtsa.
ItemTemplate testre szabható a Tervező használatával a DataList intelligens címke Sablonok szerkesztése opciója vagy közvetlenül a deklaratív szintaxis használata révén.
Hozzon létre egy szerkesztőfelületet, amely szövegként jeleníti meg a szállító nevét, de tartalmazza a szállító címének, városának és ország/régió értékeinek Szövegmezőit. A módosítások elvégzése után a lap deklaratív szintaxisának a következőhöz hasonlóan kell kinéznie:
<asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID"
DataSourceID="SuppliersDataSource">
<ItemTemplate>
<h4><asp:Label ID="CompanyNameLabel" runat="server"
Text='<%# Eval("CompanyName") %>' /></h4>
<table border="0">
<tr>
<td class="SupplierPropertyLabel">Address:</td>
<td class="SupplierPropertyValue">
<asp:TextBox ID="Address" runat="server"
Text='<%# Eval("Address") %>' />
</td>
</tr>
<tr>
<td class="SupplierPropertyLabel">City:</td>
<td class="SupplierPropertyValue">
<asp:TextBox ID="City" runat="server"
Text='<%# Eval("City") %>' />
</td>
</tr>
<tr>
<td class="SupplierPropertyLabel">Country:</td>
<td class="SupplierPropertyValue">
<asp:TextBox ID="Country" runat="server"
Text='<%# Eval("Country") %>' />
</td>
</tr>
</table>
<br />
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>
Megjegyzés:
Az előző oktatóanyaghoz hasonlóan az oktatóanyagban szereplő DataList nézetállapotának engedélyezve kell lennie.
ItemTemplate I-ben két új CSS osztályt használok, SupplierPropertyLabel és SupplierPropertyValue, amelyek hozzá lettek adva az Styles.css osztályhoz, és úgy vannak konfigurálva, hogy ugyanazokat a stílusbeállításokat használják, mint a ProductPropertyLabel és ProductPropertyValue CSS osztályok.
.ProductPropertyLabel, .SupplierPropertyLabel
{
font-weight: bold;
text-align: right;
}
.ProductPropertyValue, .SupplierPropertyValue
{
padding-right: 35px;
}
Miután végrehajtotta ezeket a módosításokat, látogasson el erre a lapra egy böngészőben. Ahogy az 5. ábrán látható, minden DataList-elem szövegként jeleníti meg a szállító nevét, és a TextBoxes használatával jeleníti meg a címet, a várost és az országot/régiót.
5. ábra: A DataList minden szállítója szerkeszthető (ide kattintva megtekintheti a teljes méretű képet)
2. lépés: Az Összes frissítése gomb hozzáadása
Bár az 5. ábrán minden szállító címe, városa és ország/régió mezője megjelenik egy Szövegmezőben, jelenleg nincs elérhető Frissítés gomb. Elemenként a Frissítés gomb helyett a teljes mértékben szerkeszthető DataLists funkcióval általában egyetlen Frissítés minden gombja található a lapon, amely kattintáskor frissíti az összes rekordot a DataListben. Ebben az oktatóanyagban adjunk hozzá két Update All gombot – egyet a lap tetején, egyet pedig alul (bár mindkét gombra kattintva ugyanaz a hatása lesz).
Először adjon hozzá egy gombweb vezérlőelemet a DataList fölé, és állítsa be a tulajdonságát ID a következőre UpdateAll1: . Ezután adja hozzá a második Button Web kontrollt a DataList alatt, és állítsa be az értékét ID-ről UpdateAll2-re. Állítsd be a Text tulajdonságait a két gombnál az Összes frissítése lehetőségre. Végül hozzon létre eseménykezelőket mindkét Button-eseményhez Click . Ahelyett, hogy a frissítési logikát minden egyes eseménykezelőnél megismételnénk, alakítsuk át ezt a logikát egy harmadik metódussá, UpdateAllSupplierAddresses úgy, hogy az eseménykezelők egyszerűen csak ezt a harmadik metódust hívják meg.
protected void UpdateAll1_Click(object sender, EventArgs e)
{
UpdateAllSupplierAddresses();
}
protected void UpdateAll2_Click(object sender, EventArgs e)
{
UpdateAllSupplierAddresses();
}
private void UpdateAllSupplierAddresses()
{
// TODO: Write code to update _all_ of the supplier addresses in the DataList
}
A 6. ábrán az Összes frissítése gomb hozzáadása utáni lap látható.
6. ábra: Két "Update All" gomb lett hozzáadva az oldalhoz (kattintson ide a teljes méretű kép megtekintéséhez)
3. lépés: Az összes szállító címadatainak frissítése
Az összes DataList-elem megjeleníti a szerkesztőfelületet, és a Frissítés minden gombja mellett csak a kötegfrissítés végrehajtásához szükséges kódot kell írni. Pontosabban végig kell lépnünk a DataList-elemeken, és mindegyikhez meg kell hívnunk az SuppliersBLL osztály s UpdateSupplierAddress metódusát.
A DataListet alkotó példányok gyűjteménye DataListItem a DataList tulajdonságánItems keresztül érhető el. Egy hivatkozással DataListItemmegragadhatjuk a megfelelőt SupplierID a DataKeys gyűjteményből, és programozott módon hivatkozhatunk a TextBox webvezérlőire a ItemTemplate következő kódban látható módon:
private void UpdateAllSupplierAddresses()
{
// Create an instance of the SuppliersBLL class
SuppliersBLL suppliersAPI = new SuppliersBLL();
// Iterate through the DataList's items
foreach (DataListItem item in Suppliers.Items)
{
// Get the supplierID from the DataKeys collection
int supplierID = Convert.ToInt32(Suppliers.DataKeys[item.ItemIndex]);
// Read in the user-entered values
TextBox address = (TextBox)item.FindControl("Address");
TextBox city = (TextBox)item.FindControl("City");
TextBox country = (TextBox)item.FindControl("Country");
string addressValue = null, cityValue = null, countryValue = null;
if (address.Text.Trim().Length > 0)
addressValue = address.Text.Trim();
if (city.Text.Trim().Length > 0)
cityValue = city.Text.Trim();
if (country.Text.Trim().Length > 0)
countryValue = country.Text.Trim();
// Call the SuppliersBLL class's UpdateSupplierAddress method
suppliersAPI.UpdateSupplierAddress
(supplierID, addressValue, cityValue, countryValue);
}
}
Amikor a felhasználó az Összes frissítése gomb egyikére kattint, a UpdateAllSupplierAddresses metódus végigfut a DataListItem elemein a Suppliers DataListben, és meghívja az SuppliersBLL osztály UpdateSupplierAddress metódusát, átadva a megfelelő értékeket. A cím, város vagy ország/régió nem megadott értéke Nothing és UpdateSupplierAddress közötti érték lesz (nem üres sztring), ami adatbázis bejegyzést eredményez az alapul szolgáló rekord mezői számára.
Megjegyzés:
Fejlesztésként érdemes lehet hozzáadni egy állapotcímke webvezérlőt a laphoz, amely megerősítést küld a kötegfrissítés végrehajtása után.
Csak a módosított címek frissítése
Az oktatóanyaghoz használt kötegelt frissítési algoritmus meghívja a UpdateSupplierAddress metódust a DataList minden szállítójára, függetlenül attól, hogy módosultak-e a címadataik. Bár az ilyen vak frissítések általában nem teljesítményproblémák, felesleges rekordokhoz vezethetnek, ha újra naplózzák az adatbázistábla módosításait. Ha például eseményindítókkal rögzíti az összes UPDATE s-t a Suppliers táblában egy naplózási táblában, minden alkalommal, amikor a felhasználó az Összes frissítése gombra kattint, egy új naplózási rekord jön létre a rendszer minden szállítója számára, függetlenül attól, hogy a felhasználó végzett-e módosításokat.
A ADO.NET DataTable és DataAdapter osztályokat úgy tervezték, hogy támogassák a kötegelt frissítéseket, ahol csak a módosított, törölt és új rekordok eredményeznek adatbázis-kommunikációt. A DataTable minden sorában van egy RowState tulajdonság , amely jelzi, hogy a sor hozzá lett-e adva a DataTable-hoz, törölve lett-e belőle, módosítva vagy változatlan marad-e. A DataTable kezdeti feltöltésekor az összes sor változatlanul lesz megjelölve. Ha a sor bármelyik oszlopának értékét megváltoztatjuk, a sor módosítottnak lesz jelölve.
SuppliersBLL Az osztályban úgy frissítjük a megadott szállítói címadatokat, hogy először beolvasjuk az egyetlen szállítói rekordot egybeSuppliersDataTable, majd a következő kóddal állítjuk be a Address, Cityés Country az oszlop értékeit:
public bool UpdateSupplierAddress
(int supplierID, string address, string city, string country)
{
Northwind.SuppliersDataTable suppliers =
Adapter.GetSupplierBySupplierID(supplierID);
if (suppliers.Count == 0)
// no matching record found, return false
return false;
else
{
Northwind.SuppliersRow supplier = suppliers[0];
if (address == null)
supplier.SetAddressNull();
else
supplier.Address = address;
if (city == null)
supplier.SetCityNull();
else
supplier.City = city;
if (country == null)
supplier.SetCountryNull();
else
supplier.Country = country;
// Update the supplier Address-related information
int rowsAffected = Adapter.Update(supplier);
// Return true if precisely one row was updated,
// otherwise false
return rowsAffected == 1;
}
}
Ez a kód naiv módon rendeli hozzá a megadott cím-, város-, és ország-/régióértékeket a SuppliersRow a SuppliersDataTable címére, függetlenül attól, hogy az értékek változtak-e. Ezek a módosítások miatt az SuppliersRow s RowState tulajdonság módosultként van megjelölve. Az adatelérési réteg metódusának Update meghívásakor azt látja, hogy a SupplierRow metódus módosult, ezért parancsot UPDATE küld az adatbázisnak.
Tegyük fel azonban, hogy ehhez a metódushoz kódot adtunk hozzá, hogy csak akkor rendeljük hozzá a megadott cím-, város- és ország-/régióértékeket, ha azok eltérnek a SuppliersRow meglévő értékektől. Abban az esetben, ha a cím, a város és az ország/régió megegyezik a meglévő adatokkal, nem történik módosítás, és az SupplierRow s-ek RowState változatlanként lesznek megjelölve. A nettó eredmény az, hogy a DAL metódus Update meghívásakor a rendszer nem fog adatbázis-hívást kezdeményezni, mert az SuppliersRow nem lett módosítva.
A módosítás végrehajtásához cserélje le azokat az utasításokat, amelyek vakon rendelik hozzá a továbbított cím, város és ország/régió értékeit a következő kódra:
// Only assign the values to the SupplierRow's column values if they differ
if (address == null && !supplier.IsAddressNull())
supplier.SetAddressNull();
else if ((address != null && supplier.IsAddressNull()) ||
(!supplier.IsAddressNull() &&
string.Compare(supplier.Address, address) != 0))
supplier.Address = address;
if (city == null && !supplier.IsCityNull())
supplier.SetCityNull();
else if ((city != null && supplier.IsCityNull()) ||
(!supplier.IsCityNull() && string.Compare(supplier.City, city) != 0))
supplier.City = city;
if (country == null && !supplier.IsCountryNull())
supplier.SetCountryNull();
else if ((country != null && supplier.IsCountryNull()) ||
(!supplier.IsCountryNull() &&
string.Compare(supplier.Country, country) != 0))
supplier.Country = country;
Ezzel a hozzáadott kóddal a DAL metódus Update csak azoknak a rekordoknak küld utasítást UPDATE az adatbázisnak, amelyek címhez kapcsolódó értékei megváltoztak.
Azt is nyomon követhetjük, hogy van-e különbség a megadott címmezők és az adatbázis adatai között, és ha nincs, egyszerűen megkerüljük a DAL metódus hívását Update . Ez a módszer jól működik, ha a közvetlen adatbázis-metódust használja, mivel ennél a közvetlen adatbázis-metódusnál nem ad át egy SuppliersRow példányt, amelynek RowState ellenőrizhető lenne annak meghatározására, hogy valóban szükséges-e egy adatbázis-hívás.
Megjegyzés:
Minden alkalommal, amikor a UpdateSupplierAddress metódust meghívják, a rendszer meghívja az adatbázist a frissített rekord adatainak lekéréséhez. Ezután, ha bármilyen változás történik az adatokban, a rendszer egy másik hívást indít az adatbázishoz a táblasor frissítéséhez. Ezt a munkafolyamatot úgy lehet optimalizálni, hogy létrehoz egy metódus-túlterhelést UpdateSupplierAddress, amely elfogad egy EmployeesDataTable példányt, amely rendelkezik az oldal BatchUpdate.aspx módosításával. Ezután egyetlen hívást indíthat az adatbázishoz, hogy lekérje az összes rekordot a Suppliers táblából. Ezután a két eredményhalmaz enumerálható, és csak azokat a rekordokat lehet frissíteni, amelyekben változások történtek.
Összefoglalás
Ebben az oktatóanyagban bemutattuk, hogyan hozhat létre teljes mértékben szerkeszthető DataListet, amely lehetővé teszi, hogy a felhasználók gyorsan módosíthassák több szállító címadatait. A szerkesztőfelület definiálásával egy TextBox webvezérlőt határoztunk meg a dataList-ek szállítói cím-, város- és ország-/régióértékeihez ItemTemplate. Ezután hozzáadtuk az Összes frissítése gombot a DataList fölött és alatt. Miután egy felhasználó végrehajtotta a módosításait, és az Összes frissítése gomb egyikére kattintott, a DataListItem-kat felsorolják, és meghívják az SuppliersBLL osztály UpdateSupplierAddress metódusát.
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 Tanuld meg ASP.NET 2.0 24 óra alatt. Ő 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 Zack Jones és Ken Pespisa voltak. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.