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
Ez az oktatóanyag bemutatja, hogyan adhat hozzá egy oszlopnyi választógombot egy GridView-vezérlőhöz, hogy a felhasználó intuitívabb módon válassza ki a GridView egyetlen sorát.
Bevezetés
A GridView vezérlő számos beépített funkciót kínál. Számos különböző mezőt tartalmaz a szöveg, a képek, a hivatkozások és a gombok megjelenítéséhez. Támogatja a további testreszabáshoz szükséges sablonokat. Az egér néhány kattintásával létrehozhat egy GridView-t, ahol minden sor kijelölhető egy gombra kattintva, vagy engedélyezheti a szerkesztési vagy törlési képességeket. A számos rendelkezésre álló funkció ellenére gyakran lesznek olyan helyzetek, amikor további, nem támogatott funkciókat kell hozzáadni. Ebben az oktatóanyagban és a következő kettőben azt vizsgáljuk meg, hogyan bővíthetjük a GridView funkcióit további funkciókkal.
Ez az oktatóanyag és a következő a sorkiválasztási folyamat fejlesztésére összpontosít. Amint azt a Master/Detail - Választható Master GridView és részlet nézetek című szakaszban megvizsgáltuk, hozzáadhatunk egy ParancsMezőt a GridView-hoz, amely tartalmaz egy kiválasztási gombot. Kattintáskor egy postback történik, és a GridView SelectedIndex tulajdonsága annak a sornak az indexére frissül, amelynek a Kijelölés gombjára kattintott. A Master/Detail Using a Selectable Master GridView with a Details DetailView oktatóanyagban láthattuk, hogyan jelenítheti meg a kiválasztott GridView sor részleteit ezzel a funkcióval.
Bár a Kiválasztás gomb sok esetben működik, előfordulhat, hogy mások számára nem működik jól. Gomb használata helyett gyakran két másik felhasználói felületi elemet használunk a kiválasztáshoz: a választógombot és a jelölőnégyzetet. Bővíthetjük a GridView-t, hogy a Kiválasztás gomb helyett minden sor tartalmaz egy választógombot vagy jelölőnégyzetet. Olyan esetekben, amikor a felhasználó csak egy GridView rekordot tud kijelölni, a választógomb előnyben részesíthető a Kiválasztás gombnál. Olyan helyzetekben, amikor a felhasználó több rekordot is kiválaszthat, például egy webalapú levelezőalkalmazásban, ahol a felhasználó több üzenetet is kijelölhet a jelölőnégyzet törléséhez, olyan funkciókat kínál, amelyek nem érhetők el a Kiválasztás gomb vagy a választógomb felhasználói felületei között.
Ez az oktatóanyag bemutatja, hogyan adhat hozzá egy oszlopnyi választógombot a GridView-hoz. A bemutató körüljárja a jelölőnégyzetek használatát.
1. lépés: A GridView-weblapok továbbfejlesztése
Mielőtt elkezdjük továbbfejleszteni a GridView-t, hogy egy oszlopnyi választógombot tartalmazzon, először szánjunk egy kis időt, hogy létrehozzuk a ASP.NET oldalakat a webhelyprojektben, amelyekre szükségünk lesz ehhez az oktatóanyaghoz és a következő kettőhöz. Első lépésként adjon hozzá egy új mappát.EnhancedGridView Ezután adja hozzá a következő ASP.NET lapokat a mappához, és mindenképpen társítsa az egyes lapokat a Site.master mesterlaphoz:
Default.aspxRadioButtonField.aspxCheckBoxField.aspxInsertThroughFooter.aspx
1. ábra: A SqlDataSource-Related oktatóanyagok ASP.NET lapjainak hozzáadása
A többi mappához Default.aspx hasonlóan a EnhancedGridView mappában is a szakasz oktatóanyagai jelennek meg. Ne feledje, hogy a SectionLevelTutorialListing.ascx Felhasználói vezérlő biztosítja ezt a funkciót. Ezért húzza ezt a felhasználói vezérlőt a Megoldáskezelőből a lap tervezési nézetébe.
2. ábra: Adja hozzá a SectionLevelTutorialListing.ascx felhasználói vezérlőt Default.aspx (kattintson ide a teljes méretű kép megtekintéséhez)
Végül adja hozzá ezt a négy lapot bejegyzésként a Web.sitemap fájlhoz. Kifejezetten adja hozzá a következő jelölést az SqlDataSource-vezérlő <siteMapNode> használata után:
<siteMapNode
title="Enhancing the GridView"
url="~/EnhancedGridView/Default.aspx"
description="Augment the user experience of the GridView control.">
<siteMapNode
url="~/EnhancedGridView/RadioButtonField.aspx"
title="Selection via a Radio Button Column"
description="Explore how to add a column of radio buttons in the GridView." />
<siteMapNode
url="~/EnhancedGridView/CheckBoxField.aspx"
title="Selection via a Checkbox Column"
description="Select multiple records in the GridView by using a column of
checkboxes." />
<siteMapNode
url="~/EnhancedGridView/InsertThroughFooter.aspx"
title="Add New Records through the Footer"
description="Learn how to allow users to add new records through the
GridView's footer." />
</siteMapNode>
A frissítés Web.sitemapután szánjon egy kis időt az oktatóanyagok webhelyének megtekintésére egy böngészőben. A bal oldali menü mostantól tartalmazza az oktatóanyagok szerkesztéséhez, beszúrásához és törléséhez szükséges elemeket.
3. ábra: A webhelytérkép most már tartalmaz bejegyzéseket a GridView-oktatóanyagok fejlesztéséhez
2. lépés: A szállítók megjelenítése a GridView-ban
Ebben az oktatóanyagban hozzunk létre egy GridView-t, amely felsorolja az USA-ból származó szállítókat, és minden GridView sor tartalmaz egy választógombot. Miután kiválasztott egy szállítót a választógombbal, a felhasználó egy gombra kattintva megtekintheti a szállító termékeit. Bár ez a feladat triviálisnak tűnhet, számos finomság teszi különösen bonyolultsá. Mielőtt belevágnánk ezekbe a finomságokba, először szerezzünk be egy GridView-t, amely felsorolja a beszállítókat.
Először nyissa meg a RadioButtonField.aspx lapot a EnhancedGridView mappában úgy, hogy a GridView-t áthúzza az eszközkészletből a Tervezőbe. Állítsa be a GridView ID elemét Suppliers értékre, majd az intelligens címkéből válassza az új adatforrás létrehozását. Pontosabban hozzon létre egy ObjectDataSource nevű SuppliersDataSource objektumot, amely lekéri az adatait az SuppliersBLL objektumból.
4. ábra: Új ObjectDataSource nevesített SuppliersDataSource létrehozása (ide kattintva megtekintheti a teljes méretű képet)
5. ábra: Az ObjectDataSource konfigurálása az SuppliersBLL osztály használatára (kattintson ide a teljes méretű kép megtekintéséhez)
Mivel csak az USA-beli szállítókat szeretnénk listázni, válassza ki a GetSuppliersByCountry(country) metódust a SELECT lap legördülő listájából.
6. ábra: Az ObjectDataSource konfigurálása az SuppliersBLL osztály használatára (kattintson ide a teljes méretű kép megtekintéséhez)
A FRISSÍTÉS lapon válassza a (Nincs) lehetőséget, és kattintson a Tovább gombra.
7. ábra: Az ObjectDataSource konfigurálása az SuppliersBLL osztály használatára (kattintson ide a teljes méretű kép megtekintéséhez)
Mivel a GetSuppliersByCountry(country) metódus elfogad egy paramétert, az Adatforrás konfigurálása varázsló kéri a paraméter forrását. Ha meg szeretne adni egy kemény kódolt értéket (ebben a példában USA), hagyja meg a Paraméter forrás legördülő listájában a Nincs értéket, és írja be az alapértelmezett értéket a szövegmezőbe. A varázsló befejezéséhez kattintson a Befejezés gombra.
8. ábra: Az USA használata a paraméter alapértelmezett értékeként (country teljes méretű kép megtekintéséhez)
A varázsló befejezése után a GridView minden szállítói adatmezőhöz tartalmaz egy BoundFieldet. Távolítsa el mind, kivéve a CompanyName, City és Country BoundFields, és nevezze át a CompanyName BoundFields HeaderText tulajdonságát Szállítóra. Ezt követően a GridView és az ObjectDataSource deklaratív szintaxisának az alábbiakhoz hasonlóan kell kinéznie.
<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="CompanyName" HeaderText="Supplier"
SortExpression="CompanyName" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="Country" HeaderText="Country"
SortExpression="Country" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL">
<SelectParameters>
<asp:Parameter DefaultValue="USA" Name="country" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
Ebben az oktatóanyagban engedélyezze a felhasználónak, hogy a kiválasztott szállító termékeit a szállítólistával megegyező oldalon vagy egy másik oldalon tekinthesse meg. Ennek kezeléséhez adjon hozzá két gombwebvezérlőt a laphoz. Beállítottam az ID e két gombot ListProducts és SendToProducts értékre, azzal a gondolattal, hogy amikor a ListProducts-ra kattintanak, egy postback fog történni, és a kiválasztott szállító termékei ugyanazon az oldalon lesznek felsorolva, de ha a SendToProducts-ra kattintanak, a felhasználót átirányítják egy másik oldalra, amely felsorolja a termékeket.
A 9. ábrán a Suppliers GridView és a két gombos webvezérlő látható, ha egy böngészőben tekinti meg.
9. ábra: Az USA-ból származó beszállítók neve, városa és országa szerepel a listán (Kattintson ide a teljes méretű kép megtekintéséhez)
3. lépés: Választókapcsolók oszlopának beillesztése
Ezen a ponton a Suppliers GridView három BoundFields jeleníti meg a cég nevét, a várost és az országot minden USA-beli szállítónál. Még mindig hiányzik egy oszlop a választógombokból. Sajnos a GridView nem tartalmaz beépített RadioButtonField elemet, különben egyszerűen hozzáadhatnánk a táblázathoz, és el is készülnénk. Ehelyett hozzáadhatunk egy TemplateFieldet, és konfigurálhatjuk úgy ItemTemplate , hogy egy választógombot jelenítsünk meg, ami egy választógombot eredményez az egyes GridView-sorokhoz.
Kezdetben feltételezhetjük, hogy a kívánt felhasználói felület implementálható úgy, hogy hozzáad egy RadioButton webvezérlőt egy ItemTemplate TemplateFieldhez. Bár ez valóban egyetlen választógombot ad hozzá a GridView minden sorához, a választógombok nem csoportosíthatók, emiatt nem kizárólagosan használhatók. Vagyis egy végfelhasználó egyszerre több választógombot is kiválaszthat a GridView-ból.
Annak ellenére, hogy a RadioButton Web-vezérlők TemplateFieldjének használata nem nyújtja a szükséges funkciókat, alkalmazzuk ezt a megközelítést, mivel érdemes megvizsgálni, hogy az eredményként kapott választógombok miért nincsenek csoportosítva. Első lépésként adjon hozzá egy TemplateFieldet a Suppliers GridView-hoz, így ez lesz a bal szélső mező. Ezután a GridView intelligens címkéjén kattintson a Sablonok szerkesztése hivatkozásra, és húzzon egy rádiógomb webvezérlőt az eszközkészletből a TemplateField ItemTemplate-jébe (lásd a 10. ábrát). Állítsa be a RadioButton ID tulajdonságát RowSelector értékre, valamint a GroupName tulajdonságát SuppliersGroup értékre.
10. ábra: RadioButton webvezérlő hozzáadása a ItemTemplate (kattintson ide a teljes méretű kép megtekintéséhez)
Miután ezeket a kiegészítéseket a Tervezőn keresztül elvégezte, a GridView-korrektúrának az alábbihoz hasonlóan kell kinéznie:
<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource"
EnableViewState="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="RowSelector" runat="server"
GroupName="SuppliersGroup" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CompanyName" HeaderText="Supplier"
SortExpression="CompanyName" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="Country" HeaderText="Country"
SortExpression="Country" />
</Columns>
</asp:GridView>
A RadioButton GroupName tulajdonság csoportosítja a választógombok sorozatát. Az azonos GroupName értékű RadioButton-vezérlők csoportosítottnak minősülnek; egyszerre csak egy választógomb választható ki egy csoportból. A GroupName tulajdonság a renderelt választógomb s attribútumának name értékét adja meg. A böngésző megvizsgálja a választógombok attribútumait a választógombok name csoportosításának meghatározásához.
Ha a RadioButton webvezérlőt hozzáadta a laphoz, látogasson el erre a ItemTemplatelapra egy böngészőben, és kattintson a rácssorok választógombjaira. Figyelje meg, hogy a választógombok nincsenek csoportosítva, így lehetőség van az összes sor kijelölésére a 11. ábrán látható módon.
11. ábra: A GridView választógombjai nincsenek csoportosítva (kattintson ide a teljes méretű kép megtekintéséhez)
A választógombok csoportosításának oka az, hogy a renderelt name attribútumaik eltérőek, annak ellenére, hogy ugyanazzal GroupName a tulajdonságbeállítással rendelkeznek. A különbségek megtekintéséhez válasszon egy nézetet/forrást a böngészőből, és vizsgálja meg a választógombok korrektúrát:
<input id="ctl00_MainContent_Suppliers_ctl02_RowSelector"
name="ctl00$MainContent$Suppliers$ctl02$SuppliersGroup"
type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl03_RowSelector"
name="ctl00$MainContent$Suppliers$ctl03$SuppliersGroup"
type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl04_RowSelector"
name="ctl00$MainContent$Suppliers$ctl04$SuppliersGroup"
type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl05_RowSelector"
name="ctl00$MainContent$Suppliers$ctl05$SuppliersGroup"
type="radio" value="RowSelector" />
Figyelje meg, hogy az name és id attribútumok nem a Tulajdonságok ablakban megadott pontos értékek, hanem néhány más ID érték is hozzá van adva. A renderelt ID és id attribútumok elejére hozzáadott további name értékek a választógombok szülővezérlőinek ID-jai, a GridView GridViewRow-ja, a Tartalomvezérlő ID-je és a Webes űrlap ID-ja. Ezek azért ID vannak hozzáadva, hogy a GridView minden renderelt webes vezérlője egyedi id és name értékekkel rendelkezik.
Minden renderelt vezérlőhöz különböző name és id szükséges, mert a böngésző így azonosítja egyedileg az ügyféloldali vezérlőket, és a webkiszolgáló számára jelzi, hogy milyen művelet vagy változás történt visszaposztoláskor. Tegyük fel például, hogy kiszolgálóoldali kódot szeretnénk futtatni, amikor a RadioButton ellenőrzött állapota módosult. Ezt úgy hajthatjuk végre, hogy AutoPostBack beállítjuk a RadioButton tulajdonságot true egy eseménykezelőre, és létrehozunk egy eseménykezelőt az CheckChanged eseményhez. Ha azonban a renderelt name és id értékei mindegyik rádiógomb esetében azonosak voltak, a postback során nem tudtuk megállapítani, hogy melyik konkrét rádiógombra kattintottak.
A rövid az, hogy nem tudunk létrehozni egy oszlop választógombok a GridView használatával RadioButton Web control. Ehelyett inkább archaikus technikákat kell használnunk annak biztosítására, hogy a megfelelő korrektúrát minden GridView sorba injektáljuk.
Megjegyzés:
A RadioButton webes vezérlőhöz hasonlóan a választógomb HTML-vezérlő is tartalmazza az egyedi name attribútumot, így a grid választógombjai nem lesznek csoportosítva. Ha nem ismeri a HTML-vezérlőket, nyugodtan hagyja figyelmen kívül ezt a megjegyzést, mivel a HTML-vezérlőket ritkán használják, különösen a ASP.NET 2.0-s verziójában. Ha azonban többet szeretne megtudni, tekintse meg K. Scott Allen blogbejegyzését, a webvezérlőket és a HTML-vezérlőket.
Rádiógomb-korrektúra beszúrása literál vezérlőelem használatával
Annak érdekében, hogy megfelelően csoportosítsuk az összes választógombot a GridView-ban, manuálisan kell beszúrnunk a választógombokat a ItemTemplatejelölőbe. Minden választógombnak ugyanazzal name az attribútummal kell rendelkeznie, de egyedi id attribútummal kell rendelkeznie (abban az esetben, ha ügyféloldali szkripttel szeretnénk elérni a választógombot). Miután egy felhasználó kiválaszt egy választógombot, és visszaküldi az oldalt, a böngésző visszaküldi a kiválasztott választógomb attribútumának value értékét. Ezért minden rádiógombnak egyedi value attribútumra lesz szüksége. Végül a visszavételkor meg kell győződnünk arról, hogy hozzáadjuk az checked attribútumot a kiválasztott egyetlen választógombhoz, különben miután a felhasználó kijelöli a választógombokat, és visszahelyezi a bejegyzéseket, a választógombok visszaállnak az alapértelmezett állapotukra (az összes nincs kiválasztva).
Az alacsony szintű korrektúra sablonba való beszúrásához két módszer érhető el. Az egyik a kód mögötti osztályban definiált korrektúra és a formázási módszerek meghívása. Ezt a technikát először a GridView Control oktatóanyag Sablonmezők használata című oktatóanyagában tárgyaltuk. Esetünkben a következőhöz hasonló lehet:
<input type="radio" id='<%# GetUniqueRadioButtonID(...) %>'
name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... />
Itt GetUniqueRadioButton és GetRadioButtonValue a kód mögötti osztályban definiált metódusok, amelyek az egyes választógombokhoz tartozó megfelelő id és value attribútumértékeket adják vissza. Ez a megközelítés jól használható a id és value attribútumok hozzárendeléséhez, azonban nem elegendő a checked attribútum értékének megadásakor, mert az adatkötési szintaxis csak akkor kerül végrehajtásra, amikor az adatok először kötődnek a GridView-hoz. Ezért, ha a GridView nézetállapota engedélyezve van, a formázási módszerek csak az oldal első betöltésekor aktiválódnak (vagy amikor a GridView kifejezetten újra van kötve az adatforráshoz), ezért az checked attribútumot beállító függvény nem lesz meghívva visszaküldéskor. Ez egy meglehetősen finom probléma, és egy kicsit túlmutat a cikk hatókörén, ezért itt hagyom. Én azonban azt javaslom, hogy próbálja meg a fenti megközelítést, és dolgozzon vele addig, amíg elakad. Bár egy ilyen gyakorlat nem fog közelebb kerülni egy működő verzióhoz, segít jobban megismerni a GridView-t és az adatkötési életciklust.
Az egyedi, alacsony szintű jelölés sablonba történő befecskendezésének másik módszere, és az ebben az oktatóanyagban alkalmazott módszer, hogy literál vezérlőelemet adunk a sablonhoz. Ezután a GridView RowCreated vagy RowDataBound eseménykezelőjében a Literal vezérlőelem programozott módon érhető el, és a Text tulajdonsága a kibocsátandó jelölőre van beállítva.
Először távolítsa el a RadioButtont a TemplateField s-ből ItemTemplate, és cserélje le egy literál vezérlőelemre. A Literál vezérlőelem s ID értékének RadioButtonMarkupbeállítása.
12. ábra: Egy 'Literal Control' hozzáadása a ItemTemplate (képhez – ide kattintva megtekintheti a teljes méretű képet)
Ezután hozzon létre egy eseménykezelőt a GridView-eseményhez RowCreated . Az RowCreated esemény minden hozzáadott sornál egyszer aktiválódik, függetlenül attól, hogy az adatok a GridView-ba kerülnek-e. Ez azt jelenti, hogy még az utópostázáskor is, amikor az adatok újratöltődnek a nézetállapottól, az RowCreated esemény továbbra is aktiválódik, és ez az oka annak, hogy azt használjuk RowDataBound helyett (ami csak akkor aktiválódik, ha az adatok kifejezetten az adatwebes vezérlőelemhez vannak kötve).
Ebben az eseménykezelőben csak akkor szeretnénk továbblépni, ha adatsorról van szó. Minden adatsor esetében programozottan hivatkozunk a RadioButtonMarkup Literál vezérlőelemre, és a Text tulajdonságát az emitálni kívánt jelölésre állítjuk. Ahogy az alábbi kód is mutatja, a kibocsátott jelölő egy olyan választógombot hoz létre, amelynek name attribútuma SuppliersGroup értékre van beállítva, id attribútuma RowSelectorX értékre van beállítva, ahol X a GridView sor indexe, és amelynek value attribútuma szintén a GridView sor indexére van beállítva.
protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Grab a reference to the Literal control
Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
// Output the markup except for the "checked" attribute
output.Text = string.Format(
@"<input type="radio" name="SuppliersGroup" " +
@"id="RowSelector{0}" value="{0}" />", e.Row.RowIndex);
}
}
Amikor ki van jelölve egy GridView-sor, és visszapostázás történik, a kiválasztott szállító SupplierID érdekel minket. Ezért azt gondolhatnánk, hogy az egyes választógombok értékének a ténylegesnek SupplierID kell lennie (nem pedig a GridView sor indexének). Bár ez bizonyos körülmények között működhet, biztonsági kockázat lenne vakon elfogadni és feldolgozni a SupplierID. A GridView például csak az USA-beli szállítókat sorolja fel. Ha azonban a SupplierID értéket közvetlenül a választógombról adjuk át, mi akadályozhatja meg, hogy egy csintalan felhasználó módosítsa a SupplierID visszaküldött értéket a visszaküldéskor? Ha a sorindexet használjuk mint value, majd a visszaküldéskor a SupplierID gyűjteményből kinyerjük a DataKeys, akkor biztosíthatjuk, hogy a felhasználó csak az egyik SupplierID értéket használja a GridView sorok közül.
Az eseménykezelő kód hozzáadása után szánjon egy percet az oldal tesztelésére egy böngészőben. Először is vegye figyelembe, hogy a rácsban egyszerre csak egy rádiógomb választható ki. Ha azonban kiválaszt egy választógombot, és az egyik gombra kattint, a visszavétel történik, és a választógombok mind visszaállnak a kezdeti állapotukra (vagyis a visszavételkor a kiválasztott választógomb már nincs kiválasztva). A probléma megoldásához ki kell egészítenünk az RowCreated eseménykezelőt úgy, hogy az megvizsgálja a postback során küldött kiválasztott rádiógomb indexet, és hozzáadja az checked="checked" attribútumot a generált jelöléshez, ha a sorindexek megegyeznek.
Ha postback történik, a böngésző küldi vissza a kiválasztott választógomb name és value. Az érték programozott módon lekérhető a következő használatával Request.Form["name"]: . A Request.Form tulajdonság az NameValueCollection űrlapváltozókat jelöli. Az űrlapváltozók a weblap űrlapmezőinek nevei és értékei, amelyeket a böngésző minden alkalommal visszaküld, amikor egy utóvisszaküldés érkezik. Mivel a rádiógombok renderelt name attribútuma a GridView-ban SuppliersGroup lesz, amikor a weblapot visszaküldik, a böngésző SuppliersGroup=valueOfSelectedRadioButton visszaküldi a webkiszolgálónak (a többi űrlapmezővel együtt). Ez az információ ezután a következővel érhető el a Request.Form tulajdonságból: Request.Form["SuppliersGroup"].
Mivel nem csak az eseménykezelőben RowCreated , hanem a Gomb webvezérlők eseménykezelőiben Click is meg kell határoznunk a kiválasztott választógomb-indexet, adjunk hozzá egy SuppliersSelectedIndex tulajdonságot a kód mögötti osztályhoz, amely akkor ad vissza -1 , ha nincs választógomb kijelölve, és a kiválasztott indexet, ha valamelyik választógomb van kiválasztva.
private int SuppliersSelectedIndex
{
get
{
if (string.IsNullOrEmpty(Request.Form["SuppliersGroup"]))
return -1;
else
return Convert.ToInt32(Request.Form["SuppliersGroup"]);
}
}
Ezzel a tulajdonsággal tudjuk, hogy a checked="checked" jelölést az RowCreated eseménykezelőbe kell helyezni, amikor SuppliersSelectedIndex egyenlő e.Row.RowIndex-mal. Frissítse az eseménykezelőt úgy, hogy tartalmazza ezt a logikát:
protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Grab a reference to the Literal control
Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
// Output the markup except for the "checked" attribute
output.Text = string.Format(
@"<input type="radio" name="SuppliersGroup" " +
@"id="RowSelector{0}" value="{0}"", e.Row.RowIndex);
// See if we need to add the "checked" attribute
if (SuppliersSelectedIndex == e.Row.RowIndex)
output.Text += @" checked="checked"";
// Add the closing tag
output.Text += " />";
}
}
Ezzel a módosítással a kiválasztott választógomb az adatvisszaküldés után is kiválasztva marad. Most, hogy meg tudjuk adni, hogy melyik választógomb van kiválasztva, módosíthatjuk a viselkedést, hogy az oldal első megnyitásakor az első GridView sor választógombja legyen kiválasztva (ahelyett, hogy alapértelmezés szerint nem lettek kiválasztva a választógombok, ami az aktuális viselkedés). Ha alapértelmezés szerint az első választógombot szeretné kijelölni, egyszerűen módosítsa az utasítást if (SuppliersSelectedIndex == e.Row.RowIndex) a következőre: if (SuppliersSelectedIndex == e.Row.RowIndex || (!Page.IsPostBack && e.Row.RowIndex == 0)).
Ezen a ponton egy csoportosított választógombokat tartalmazó oszlopot adtunk hozzá a GridView-hoz, amely lehetővé teszi, hogy egyetlen GridView-sort jelöljön ki és megőrizzen a postbackek során. A következő lépés a kiválasztott szállító által biztosított termékek megjelenítése. A 4. lépésben látni fogjuk, hogyan irányítsuk át a felhasználót egy másik oldalra, a kijelölt SupplierID elküldésével együtt. Az 5. lépésben látni fogjuk, hogyan jelenítheti meg a kiválasztott szállító termékeit egy GridView-ban ugyanazon az oldalon.
Megjegyzés:
Sablonmező használata (a hosszú 3. lépés fókusza) helyett létrehozhatunk egy egyéni DataControlField osztályt, amely a megfelelő felhasználói felületet és funkciókat jeleníti meg. Az DataControlField osztály az az alaposztály, amelyből a BoundField, a CheckBoxField, a TemplateField és más beépített GridView és DetailsView mezők származnak. Az egyéni DataControlField osztály létrehozása azt jelentené, hogy a választógombok oszlopa csak deklaratív szintaxissal adható hozzá, és jelentősen megkönnyítené a más weboldalakon és más webalkalmazások funkcióinak replikálását is.
Ha valaha is létrehozott egyéni, fordított vezérlőket ASP.NET-ben, tudja, hogy ez alapos előkészületeket igényel, és magában foglal számos finomságot és nehézséget, amelyeket gondosan kell kezelni. Ezért egyelőre lemondunk a választógombok oszlopának egyéni DataControlField osztályként való bevezetéséről, és ragaszkodunk a TemplateField beállításhoz. Lehetséges, hogy egy későbbi oktatóanyagban megismerhetjük az egyéni DataControlField osztályok létrehozását, használatát és üzembe helyezését!
4. lépés: A kiválasztott szállító termékeinek megjelenítése külön lapon
Miután a felhasználó kiválasztott egy GridView sort, meg kell jeleníteni a kiválasztott szállító termékeit. Bizonyos körülmények között előfordulhat, hogy ezeket a termékeket külön lapon szeretnénk megjeleníteni, másokban inkább ugyanabban az oldalon. Először vizsgáljuk meg, hogyan jeleníthetők meg a termékek egy külön oldalon; az 5. lépésben egy GridView-t adunk hozzá a kiválasztott szállító termékeinek megjelenítéséhez RadioButtonField.aspx .
Jelenleg két gombos webvezérlő található a lapon ListProducts és SendToProductsa . Ha a SendToProducts gombra kattint, a felhasználót ~/Filtering/ProductsForSupplierDetails.aspxa következő címre szeretnénk elküldeni: Ez a lap a Master/Detail Filtering Across Two Pages oktatóanyagban lett létrehozva, és megjeleníti a szállító termékeit, amelyek SupplierID áthaladnak a névvel ellátott SupplierIDlekérdezési mezőn.
A funkció biztosításához hozzon létre egy eseménykezelőt a SendToProducts Button s Click eseményhez. A 3. lépésben hozzáadtuk a SuppliersSelectedIndex tulajdonságot, amely annak a sornak az indexét adja vissza, amelynek a választógombja ki van választva. A megfelelő SupplierID lekérhető a GridView DataKeys gyűjteményéből, és a felhasználó ezután elküldhető a ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID címre Response.Redirect("url").
protected void SendToProducts_Click(object sender, EventArgs e)
{
// Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
int supplierID =
Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
Response.Redirect(
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID="
+ supplierID);
}
}
Ez a kód csodálatosan működik, amíg az egyik választógomb ki van jelölve a GridView-ben. Ha kezdetben a GridView-ban nincs kiválasztva egyetlen választógomb sem, és a felhasználó a SendToProducts gombra kattint, SuppliersSelectedIndex-1 lesz, ami kivételt okoz, mivel -1 kívül esik a DataKeys gyűjtemény indextartományán. Ez azonban nem jelent problémát, ha úgy döntött, hogy frissíti az RowCreated eseménykezelőt a 3. lépésben ismertetettek szerint, hogy a GridView-ban az első rádiógomb legyen alapértelmezetten kiválasztva.
A SuppliersSelectedIndex érték elhelyezéséhez adjon hozzá egy címke webvezérlőt az oldalhoz a GridView fölé. Állítsa be a ID tulajdonságát ChooseSupplierMsg-re, a CssClass tulajdonságát Warning-ra, a EnableViewState és Visible tulajdonságait false-ra, valamint a Text tulajdonságát a következőre: Kérjük, válasszon egy szállítót a rácsból. A CSS-osztály Warning piros, dőlt, félkövér, nagy betűtípussal jeleníti meg a szöveget, és a következőben van definiálva: Styles.css. A EnableViewState és Visible tulajdonságok false értékre állításával a címke nem lesz megjelenítve, kivéve azokat a postbackeket, amelyek során a vezérlő Visible tulajdonsága programozott módon true értékre van állítva.
13. ábra: Címke webvezérlő hozzáadása a GridView fölé (kattintson ide a teljes méretű kép megtekintéséhez)
Ezután bővítse ki az Click eseménykezelőt a ChooseSupplierMsg címke megjelenítéséhez, ha SuppliersSelectedIndex kisebb, mint nulla, és irányítsa át a felhasználót másra ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID .
protected void SendToProducts_Click(object sender, EventArgs e)
{
// make sure one of the radio buttons has been selected
if (SuppliersSelectedIndex < 0)
ChooseSupplierMsg.Visible = true;
else
{
// Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
int supplierID =
Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
Response.Redirect(
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID="
+ supplierID);
}
}
Nyissa meg a lapot egy böngészőben, és kattintson a gombra, SendToProducts mielőtt kiválaszt egy szállítót a GridView-ból. Ahogy a 14. ábra mutatja, ez megjeleníti a címkét ChooseSupplierMsg . Ezután válasszon ki egy szállítót, és kattintson a SendToProducts gombra. Ez egy olyan oldalra irányítja, amely felsorolja a kiválasztott szállító által biztosított termékeket. A 15. ábra a ProductsForSupplierDetails.aspx oldalt mutatja, amikor a Bigfoot Sörfőzdék szállítóját kiválasztották.
14. ábra: A ChooseSupplierMsg címke akkor jelenik meg, ha nincs kijelölve szállító (kattintson ide a teljes méretű kép megtekintéséhez)
15. ábra: A kiválasztott szállítói termékek megjelennek (ProductsForSupplierDetails.aspxkattintson ide a teljes méretű kép megtekintéséhez)
5. lépés: A kiválasztott szállító termékeinek megjelenítése ugyanazon az oldalon
A 4. lépésben láttuk, hogyan küldheti el a felhasználót egy másik weblapra a kiválasztott szállító termékeinek megjelenítéséhez. Másik lehetőségként a kiválasztott szállító termékei ugyanazon az oldalon is megjeleníthetők. Ennek szemléltetéséhez hozzáadunk egy másik GridView-t a kiválasztott szállító termékeinek megjelenítéséhez RadioButtonField.aspx .
Mivel csak azt szeretnénk, hogy a termékek GridView-ja a szállító kiválasztása után jelenjen meg, adjon hozzá egy Panel webvezérlőt a Suppliers GridView alá, és állítsa be annak ID értékét ProductsBySupplierPanel-re és Visible tulajdonságát false-re. A panelen adja hozzá a Kijelölt szállító termékei szöveget, majd egy GridView nevű ProductsBySupplier elemet. A GridView intelligens címkéje alapján úgy dönt, hogy egy új ObjectDataSource-hoz ProductsBySupplierDataSourceköti.
16. ábra: A GridView kötése ProductsBySupplier egy új ObjectDataSource-hoz (ide kattintva megtekintheti a teljes méretű képet)
Ezután konfigurálja az ObjectDataSource-t az ProductsBLL osztály használatára. Mivel csak a kiválasztott szállító által biztosított termékeket szeretnénk lekérni, adja meg, hogy az ObjectDataSource meghívja a metódust az GetProductsBySupplierID(supplierID) adatok lekéréséhez. Válassza a (Nincs) lehetőséget az UPDATE, INSERT és DELETE lap legördülő listái közül.
17. ábra: Az ObjectDataSource konfigurálása a GetProductsBySupplierID(supplierID) metódus használatára (kattintson ide a teljes méretű kép megtekintéséhez)
18. ábra: Állítsa a Drop-Down listákat (Nincs) az UPDATE, INSERT és DELETE lapokon (kattintson a teljes méretű kép megjelenítéséhez)
A SELECT, UPDATE, INSERT és DELETE lap konfigurálása után kattintson a Tovább gombra. Mivel a GetProductsBySupplierID(supplierID) metódus bemeneti paramétert vár, az Adatforrás létrehozása varázsló kéri, hogy adja meg a paraméter s értékének forrását.
Itt néhány lehetőségünk van a paraméter értékének forrásának megadására. Használhatjuk az alapértelmezett Paraméter objektumot, és programozott módon rendelhetjük hozzá a SuppliersSelectedIndex tulajdonság értékét az ObjectDataSource eseménykezelőjének Paraméter s DefaultValue tulajdonságához Selecting . Tekintsen vissza az ObjectDataSource paraméterértékeinek programozott módon történő beállításáról szóló oktatóanyagra az emlékeztetőért, amely bemutatja, hogyan rendelhetünk programozott módon értékeket az ObjectDataSource paramétereihez.
Másik lehetőségként használhatjuk a ControlParametert, és hivatkozhatunk a Suppliers GridView tulajdonságáraSelectedValue (lásd a 19. ábrát). A GridView tulajdonság SelectedValue a DataKeytulajdonságnakSelectedIndex megfelelő értéket adja vissza. Ahhoz, hogy ez a beállítás működjön, programozott módon be kell állítani a GridView tulajdonságot SelectedIndex a kijelölt sorra, amikor a ListProducts gombra kattint. A további előny, hogy a SelectedIndex beállításával a kiválasztott rekord a SelectedRowStyle témában meghatározott (sárga háttér) DataWebControls tulajdonságokat veszi fel.
19. ábra: A ControlParameter használata a GridView kiválasztott értékének paraméterforrásként való megadásához (kattintson ide a teljes méretű kép megtekintéséhez)
A varázsló befejezése után a Visual Studio automatikusan hozzáad mezőket a termék adatmezőihez. Távolítsa el a ProductName, CategoryName, és UnitPrice BoundFields mezőket, és módosítsa a HeaderText tulajdonságokat Termék, Kategória és Ár értékre. Konfigurálja a UnitPrice BoundFieldet úgy, hogy az értéke pénznemként legyen formázva. A módosítások elvégzése után a Panel, a GridView és az ObjectDataSource deklaratív korrektúra a következőképpen fog kinézni:
<asp:Panel runat="server" ID="ProductsBySupplierPanel" Visible="False">
<h3>
Products for the Selected Supplier</h3>
<p>
<asp:GridView ID="ProductsBySupplier" runat="server"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsBySupplierDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsBySupplierDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
<SelectParameters>
<asp:ControlParameter ControlID="Suppliers" Name="supplierID"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
</p>
</asp:Panel>
A feladat elvégzéséhez be kell állítanunk a GridView SelectedIndex tulajdonságát a SelectedSuppliersIndex-re, és a ProductsBySupplierPanel Panel Visible tulajdonságát true-re, amikor a ListProducts gombra kattintunk. Ehhez hozzon létre egy eseménykezelőt a ListProducts Button Web Control eseményéhez Click , és adja hozzá a következő kódot:
protected void ListProducts_Click(object sender, EventArgs e)
{
// make sure one of the radio buttons has been selected
if (SuppliersSelectedIndex < 0)
{
ChooseSupplierMsg.Visible = true;
ProductsBySupplierPanel.Visible = false;
}
else
{
// Set the GridView's SelectedIndex
Suppliers.SelectedIndex = SuppliersSelectedIndex;
// Show the ProductsBySupplierPanel panel
ProductsBySupplierPanel.Visible = true;
}
}
Ha egy szállító nincs kiválasztva a GridView-ból, megjelenik a ChooseSupplierMsg címke, és elrejti a ProductsBySupplierPanel panelt. Máskülönben, ha egy szállító van kiválasztva, a ProductsBySupplierPanel megjelenik, és a GridView SelectedIndex tulajdonság frissül.
A 20. ábra az eredményeket mutatja, miután a Bigfoot Sörfőzdék szállítója ki lett választva, és a Termékek megjelenítése az oldalon gombra kattintott.
20. ábra: A Bigfoot Sörfőzdék által biztosított termékek ugyanazon az oldalon vannak felsorolva (kattintson a teljes méretű kép megtekintéséhez)
Összefoglalás
Amint azt a Master/Detail Using a Selectable Master GridView with a Details DetailView oktatóanyag ismerteti, a rekordok egy CommandField használatával jelölhetők ki a GridView-ból, amelynek ShowSelectButton tulajdonsága true értékre van állítva. A CommandField azonban normál nyomógombként, hivatkozásként vagy képként jeleníti meg a gombokat. Az alternatív megoldás a sorkijelölési felhasználói felületre az, ha minden GridView sorban rádiógombot vagy jelölőnégyzetet biztosítunk. Ebben az oktatóanyagban azt vizsgáltuk, hogyan adhat hozzá egy oszlopnyi rádiogombot.
Sajnos a választógombok oszlopának hozzáadása nem olyan egyszerű vagy magától értetődő, mint amire számítani lehetne. Nincs beépített RadioButtonField, amely egy gomb kattintásával adható hozzá, és a RadioButton Web vezérlőelem használata a TemplateFieldben saját problémákat okoz. Végül egy ilyen felület biztosításához létre kell hoznunk egy egyéni DataControlField osztályt, vagy a megfelelő HTML-t kell injektálnunk egy TemplateFieldbe az RowCreated esemény során.
Miután megvizsgáltuk, hogyan adhatunk hozzá egy oszlopnyi választógombot, fordítsuk figyelmünket egy jelölőnégyzetek oszlopának hozzáadására. A jelölőnégyzetek oszlopában a felhasználó kijelölhet egy vagy több GridView-sort, majd végrehajthat néhány műveletet az összes kijelölt sorban (például kiválaszthat egy e-mail-készletet egy webes levelezőprogramból, majd törölheti az összes kijelölt e-mailt). A következő oktatóanyagban látni fogjuk, hogyan adhat hozzá ilyen oszlopot.
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ője David Suru volt. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.