Applicazione di filtri al report master o di dettaglio usando due controlli DropDownList (VB)

di Scott Mitchell

Scarica il PDF

Questa esercitazione espande la relazione master/dettaglio per aggiungere un terzo livello usando due controlli DropDownList per selezionare i record padre e nonni desiderati.

Introduzione

Nell'esercitazione precedente è stato esaminato come visualizzare un semplice report master/dettagli usando un singolo elenco DropDownList popolato con le categorie e un Controllo GridView che mostra i prodotti che appartengono alla categoria selezionata. Questo modello di report funziona correttamente durante la visualizzazione di record che hanno una relazione uno-a-molti e può essere facilmente esteso per lavorare per scenari che includono più relazioni uno-a-molti. Ad esempio, un sistema di immissione dell'ordine include tabelle corrispondenti ai clienti, agli ordini e agli elementi della riga di ordine. Un determinato cliente può avere più ordini con ogni ordine costituito da più elementi. Tali dati possono essere presentati all'utente con due DropDownList e un GridView. Il primo DropDownList ha un elemento elenco per ogni cliente nel database con il contenuto del secondo che è l'ordine inserito dal cliente selezionato. GridView elenca gli elementi della riga dall'ordine selezionato.

Anche se il database Northwind include le informazioni sui dettagli del cliente/ordine/ordine canoniche nelle Customersrelative tabelle , Orderse Order Details , queste tabelle non vengono acquisite nell'architettura. Tuttavia, è comunque possibile illustrare l'uso di due DropDownList dipendenti. Il primo DropDownList elenca le categorie e il secondo i prodotti appartenenti alla categoria selezionata. DetailsView elenca quindi i dettagli del prodotto selezionato.

Passaggio 1: Creazione e popolamento delle categorie Elenco a discesa

Il primo obiettivo è aggiungere l'elenco a discesa che elenca le categorie. Questi passaggi sono stati esaminati in dettaglio nell'esercitazione precedente, ma sono riepilogati qui per la completezza.

Aprire la MasterDetailsDetails.aspx pagina nella Filtering cartella, aggiungere un elenco a discesa alla pagina, impostarne la ID proprietà su Categoriese quindi fare clic sul collegamento Configura origine dati nel relativo smart tag. Dalla Configurazione guidata origine dati scegliere di aggiungere una nuova origine dati.

Aggiungere una nuova origine dati per l'elenco a discesa

Figura 1: Aggiungere una nuova origine dati per l'elenco a discesa (fare clic per visualizzare l'immagine full-size)

La nuova origine dati deve essere naturalmente un oggetto ObjectDataSource. Assegnare il nome a questo nuovo ObjectDataSource CategoriesDataSource e richiamarlo al CategoriesBLL metodo dell'oggetto GetCategories() .

Scegliere di usare la classe CategoriesBLL

Figura 2: Scegliere di usare la classe (fare clic per visualizzare l'immagineCategoriesBLL full-size)

Configurare ObjectDataSource per usare il metodo GetCategories()

Figura 3: Configurare ObjectDataSource per usare il GetCategories() metodo (fare clic per visualizzare l'immagine full-size)

Dopo aver configurato ObjectDataSource, è comunque necessario specificare quale campo origine dati deve essere visualizzato nell'elenco Categories a discesa e quale deve essere configurato come valore per l'elemento di elenco. Impostare il CategoryName campo come visualizzazione e CategoryID come valore per ogni elemento dell'elenco.

Visualizzare il campo CategoryName e usare CategoryID come valore

Figura 4: Visualizzare il campo e usare CategoryID come valore (fare clic per visualizzare l'immagineCategoryName a dimensioni complete)

A questo punto è disponibile un controllo DropDownList (Categories) popolato con i record della Categories tabella. Quando l'utente sceglie una nuova categoria da DropDownList, si vuole che venga eseguito un postback per aggiornare l'elenco a discesa del prodotto che verrà creato nel passaggio 2. Selezionare quindi l'opzione Abilita AutoPostBack dallo categories smart tag di DropDownList.

Abilitare AutoPostBack per l'elenco a discesa Categorie

Figura 5: Abilitare AutoPostBack per DropDownList (Fare clic per visualizzare l'immagineCategories a dimensioni complete)

Passaggio 2: Visualizzazione dei prodotti della categoria selezionata in un secondo elenco a discesa

Al termine dell'elenco Categories a discesa, il passaggio successivo consiste nel visualizzare un elenco a discesa dei prodotti appartenenti alla categoria selezionata. A tale scopo, aggiungere un altro Elenco a discesa alla pagina denominata ProductsByCategory. Come per Categories DropDownList, creare un nuovo OggettoDataSource per ProductsByCategory DropDownList denominato ProductsByCategoryDataSource.

Aggiungere una nuova origine dati per ProductsByCategory DropDownList

Figura 6: Aggiungere una nuova origine dati per l'elenco a discesa (fare clic per visualizzare l'immagineProductsByCategory full-size)

Creare un nuovo oggettoDataSource denominato ProductsByCategoryDataSource

Figura 7: Creare un nuovo oggettoDataSource denominato ProductsByCategoryDataSource (fare clic per visualizzare l'immagine a dimensioni complete)

ProductsByCategory Poiché DropDownList deve visualizzare solo i prodotti appartenenti alla categoria selezionata, è necessario richiamare il GetProductsByCategoryID(categoryID) metodo dall'oggetto ProductsBLL ObjectDataSource.

Screenshot della finestra Configura origine dati - productsByCategoryDataSource che visualizza il menu a discesa dell'oggetto business con ProductsBLL selezionato e il pulsante Avanti evidenziato.

Figura 8: Scegliere di usare la classe (fare clic per visualizzare l'immagineProductsBLL full-size)

Configurare ObjectDataSource per usare il metodo GetProductsByCategoryID(categoryID)

Figura 9: Configurare ObjectDataSource per usare il GetProductsByCategoryID(categoryID) metodo (fare clic per visualizzare l'immagine a dimensioni complete)

Nel passaggio finale della procedura guidata è necessario specificare il valore del categoryID parametro. Assegnare questo parametro all'elemento Categories selezionato da DropDownList.

Eseguire il pull del valore del parametro categoryID dall'elenco a discesa Categorie

Figura 10: eseguire il pull del valore del parametro dall'elenco a discesa (fare clic per visualizzare l'immaginecategoryIDCategories full-size)

Con ObjectDataSource configurato, tutto ciò che rimane consiste nel specificare quali campi di origine dati vengono usati per la visualizzazione e il valore degli elementi di DropDownList. Visualizzare il campo e usare il ProductNameProductID campo come valore.

Specificare i campi origine dati usati per le proprietà Di testo e valore di DropDownList's ListItems

Figura 11: specificare i campi origine dati usati per le proprietà e Value le proprietà dell'elenco TextListItem a discesa (fare clic per visualizzare l'immagine full-size)

Con ObjectDataSource e ProductsByCategory DropDownList configurato la pagina visualizzerà due DropDownList: la prima elenca tutte le categorie mentre la seconda elenca i prodotti appartenenti alla categoria selezionata. Quando l'utente seleziona una nuova categoria dal primo DropDownList, verrà eseguito un postback e il secondo DropDownList verrà rebound, che mostra i prodotti che appartengono alla categoria appena selezionata. Le figure 12 e 13 mostrano MasterDetailsDetails.aspx in azione quando vengono visualizzate tramite un browser.

Quando si visita per la prima volta la pagina, la categoria Bevande è selezionata

Figura 12: quando si visita per la prima volta la pagina, la categoria Bevande è selezionata (fare clic per visualizzare l'immagine full-size)

Scelta di una categoria diversa visualizza i prodotti della nuova categoria

Figura 13: scelta di una categoria diversa visualizza i prodotti della nuova categoria (fare clic per visualizzare l'immagine full-size)

productsByCategory Attualmente DropDownList, quando modificato, non causa un postback. Tuttavia, si vuole che un postback venga eseguito dopo aver aggiunto un oggetto DetailsView per visualizzare i dettagli del prodotto selezionato (passaggio 3). Selezionare quindi la casella di controllo Enable AutoPostBack (Abilita autoPostBack) dal productsByCategory smart tag di DropDownList.

Abilitare la funzionalità AutoPostBack per i prodottiByCategory DropDownList

Figura 14: Abilitare la funzionalità AutoPostBack per l'elenco a discesa (Fare clic per visualizzare l'immagineproductsByCategory full-size)

Passaggio 3: Uso di un oggetto DetailsView per visualizzare i dettagli per il prodotto selezionato

Il passaggio finale consiste nel visualizzare i dettagli per il prodotto selezionato in un oggetto DetailsView. A tale scopo, aggiungere un oggetto DetailsView alla pagina, impostare la relativa ID proprietà su ProductDetailse creare un nuovo OggettoDataSource per tale pagina. Configurare ObjectDataSource per eseguire il pull dei dati dal ProductsBLL metodo della classe usando il valore selezionato di GetProductByProductID(productID) DropDownList per il valore ProductsByCategory del productID parametro.

Screenshot della finestra Configura origine dati - productsByCategoryDataSource con il menu a discesa oggetto business aperto. ProductsBLL è selezionato e il pulsante Avanti è evidenziato.

Figura 15: scegliere di usare la classe (fare clic per visualizzare l'immagineProductsBLL full-size)

Configurare ObjectDataSource per usare il metodo GetProductByProductID(productID)

Figura 16: Configurare ObjectDataSource per usare il metodo (fare clic per visualizzare l'immagineGetProductByProductID(productID) a dimensioni complete)

Eseguire il pull del valore del parametro productID dall'elenco a discesa ProductsByCategory

Figura 17: Eseguire il pull del valore del parametro dall'elenco a discesa (fare clic per visualizzare l'immagineproductIDProductsByCategory full-size)

È possibile scegliere di visualizzare uno dei campi disponibili in ProductDetails DetailsView. Sono stato scelto di rimuovere i ProductIDcampi , SupplierIDe e CategoryID riordinati e formattati i campi rimanenti. Inoltre, ho cancellato le proprietà e Width di DetailsView, consentendo a DetailsView Height di espandere la larghezza necessaria per visualizzare meglio i dati anziché avere una dimensione specificata. Il markup completo viene visualizzato di seguito:

<asp:DetailsView ID="ProductDetails" runat="server"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Fields>
        <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="QuantityPerUnit"
           HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice"
           DataFormatString="{0:c}" HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
            HeaderText="UnitsInStock"
            SortExpression="Units In Stock" />
        <asp:BoundField DataField="UnitsOnOrder"
            HeaderText="UnitsOnOrder"
            SortExpression="Units On Order" />
        <asp:BoundField DataField="ReorderLevel"
            HeaderText="ReorderLevel" SortExpression="Reorder Level" />
        <asp:CheckBoxField DataField="Discontinued"
            HeaderText="Discontinued" SortExpression="Discontinued" />
    </Fields>
</asp:DetailsView>

Provare la MasterDetailsDetails.aspx pagina in un browser. A prima vista potrebbe sembrare che tutto funzioni come desiderato, ma c'è un problema sottile. Quando si sceglie una nuova categoria, ProductsByCategory DropDownList viene aggiornata per includere tali prodotti per la categoria selezionata, ma ProductDetails DetailsView ha continuato a visualizzare le informazioni sul prodotto precedenti. DetailsView viene aggiornato quando si sceglie un prodotto diverso per la categoria selezionata. Inoltre, se si testa abbastanza attentamente, si noterà che se si sceglie continuamente nuove categorie (ad esempio scegliendo Bevande da Categories DropDownList, quindi Condiments, confections) ogni altra selezione di categorie causa l'aggiornamento ProductDetails di DetailsView.

Per concretizzare questo problema, si esaminerà un esempio specifico. Quando si visita per la prima volta la pagina la categoria Bevande viene selezionata e i prodotti correlati vengono caricati nell'elenco ProductsByCategory a discesa. Chai è il prodotto selezionato e i relativi dettagli vengono visualizzati in DetailsView, come illustrato nella ProductDetails figura 18.

I dettagli del prodotto selezionato vengono visualizzati in un oggetto DetailsView

Figura 18: i dettagli del prodotto selezionato vengono visualizzati in un oggetto DetailsView (Fare clic per visualizzare un'immagine full-size)

Se si modifica la selezione della categoria da Drinks a Condiments, si verifica un postback e l'elenco ProductsByCategory DropDownList viene aggiornato di conseguenza, ma DetailsView visualizza ancora i dettagli per Chai.

I dettagli del prodotto selezionato in precedenza sono ancora visualizzati

Figura 19: I dettagli del prodotto selezionato in precedenza sono ancora visualizzati (fare clic per visualizzare l'immagine a dimensione intera)

La selezione di un nuovo prodotto dall'elenco aggiorna DetailsView come previsto. Se si seleziona una nuova categoria dopo aver modificato il prodotto, detailsView non verrà aggiornato di nuovo. Tuttavia, se invece di scegliere un nuovo prodotto è stata selezionata una nuova categoria, detailsView verrà aggiornato. Cosa sta succedendo qui al mondo?

Il problema è un problema di temporizzazione nel ciclo di vita della pagina. Ogni volta che viene richiesta una pagina, viene eseguita una serie di passaggi durante il rendering. In uno di questi passaggi i controlli ObjectDataSource controllano se uno dei relativi SelectParameters valori è stato modificato. In tal caso, il controllo Web dati associato a ObjectDataSource sa che deve aggiornarne la visualizzazione. Ad esempio, quando viene selezionata una nuova categoria, ProductsByCategoryDataSource ObjectDataSource rileva che i relativi valori dei parametri sono stati modificati e ProductsByCategory dropDownList viene riassociato, ottenendo i prodotti per la categoria selezionata.

Il problema che si verifica in questa situazione è che il punto del ciclo di vita della pagina verificato da ObjectDataSources per verificare la presenza di parametri modificati si verifica prima del riassociamento dei controlli Web dati associati. Pertanto, quando si seleziona una nuova categoria ProductsByCategoryDataSource , ObjectDataSource rileva una modifica nel valore del parametro. ObjectDataSource usato da ProductDetails DetailsView, tuttavia, non annota tali modifiche perché ProductsByCategory DropDownList deve ancora essere rimbalzato. Più avanti nel ciclo di vita, ProductsByCategory DropDownList viene riassociato a ObjectDataSource, afferrando i prodotti per la categoria appena selezionata. Mentre il ProductsByCategory valore di DropDownList è stato modificato, il ProductDetails controllo ObjectDataSource di DetailsView ha già eseguito il controllo del valore del parametro. Di conseguenza, DetailsView visualizza i risultati precedenti. Questa interazione è illustrata nella figura 20.

Il valore dell'elenco a discesa ProductsByCategory cambia dopo che il controllo ObjectDataSource di ProductDetails DetailsView verifica la presenza di modifiche

Figura 20: Il ProductsByCategory valore dell'elenco a discesa cambia dopo il controllo ObjectDataSource di DetailsView verifica la presenza di modifiche (fare clic per visualizzare l'immagineProductDetails a dimensione intera)

Per risolvere questo problema, è necessario riassociare in modo esplicito detailsView ProductDetails dopo l'associazione ProductsByCategory di DropDownList. A tale scopo, è possibile chiamare il ProductDetails metodo detailsView DataBind() quando viene generato l'evento ProductsByCategoryDataBound dropDownList. Aggiungere il codice del gestore eventi seguente alla MasterDetailsDetails.aspx classe code-behind della pagina (fare riferimento a "Impostazione a livello di codice dei valori dei parametri di ObjectDataSource" per una discussione su come aggiungere un gestore eventi):

Protected Sub ProductsByCategory_DataBound(sender As Object, e As EventArgs) _
    Handles ProductsByCategory.DataBound
        ProductDetails.DataBind()
End Sub

Dopo aver aggiunto questa ProductDetails chiamata esplicita al metodo detailsView DataBind() , l'esercitazione funziona come previsto. La figura 21 evidenzia il modo in cui questa modifica ha risolto il problema precedente.

ProductDetails DetailsView viene aggiornato in modo esplicito quando viene generato l'evento DataBoundList di ProductsByCategory

Figura 21: DetailsView ProductDetails viene aggiornato in modo esplicito quando viene generato l'evento ProductsByCategory dell'elenco DataBound a discesa (fare clic per visualizzare l'immagine a dimensione intera)

Riepilogo

DropDownList funge da elemento dell'interfaccia utente ideale per i report master/dettagli in cui esiste una relazione uno-a-molti tra i record master e di dettaglio. Nell'esercitazione precedente è stato illustrato come usare un singolo oggetto DropDownList per filtrare i prodotti visualizzati dalla categoria selezionata. In questa esercitazione è stato sostituito GridView dei prodotti con un oggetto DropDownList e è stato usato un controllo DetailsView per visualizzare i dettagli del prodotto selezionato. I concetti illustrati in questa esercitazione possono essere facilmente estesi ai modelli di dati che coinvolgono più relazioni uno-a-molti, ad esempio clienti, ordini ed elementi degli ordini. In generale, è sempre possibile aggiungere un oggetto DropDownList per ognuna delle entità "una" nelle relazioni uno-a-molti.

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, disponibile all'indirizzo http://ScottOnWriting.NET.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale di questa esercitazione era Hilton Giesenow. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciami una riga in mitchell@4GuysFromRolla.com.