Condividi tramite


Personalizzazione dell'interfaccia di modifica di DataList (C#)

di Scott Mitchell

Scarica PDF

In questa esercitazione verrà creata un'interfaccia di modifica più completa per DataList, una che include DropDownLists e checkBox.

Introduzione

I controlli markup e Web in DataList EditItemTemplate definiscono la relativa interfaccia modificabile. In tutti gli esempi di DataList modificabili esaminati finora, l'interfaccia modificabile è costituita da controlli Web TextBox. Nell'esercitazione precedente è stata migliorata l'esperienza utente in fase di modifica aggiungendo controlli di convalida.

Può EditItemTemplate essere ulteriormente espanso per includere controlli Web diversi da TextBox, ad esempio DropDownLists, RadioButtonLists, Calendari e così via. Come per gli oggetti TextBoxes, quando si personalizza l'interfaccia di modifica per includere altri controlli Web, seguire questa procedura:

  1. Aggiungere il controllo Web a EditItemTemplate.
  2. Utilizzare la sintassi di associazione dati per assegnare il valore del campo dati corrispondente alla proprietà appropriata.
  3. UpdateCommand Nel gestore eventi accedere a livello di codice al valore del controllo Web e passarlo al metodo BLL appropriato.

In questa esercitazione verrà creata un'interfaccia di modifica più completa per DataList, una che include DropDownLists e checkBox. In particolare, verrà creato un oggetto DataList che elenca le informazioni sul prodotto e consente di aggiornare il nome, il fornitore, la categoria e lo stato di interruzione del prodotto (vedere la figura 1).

L'interfaccia di modifica include un controllo TextBox, due elenchi a discesa e un controllo CheckBox

Figura 1: L'interfaccia di modifica include un controllo TextBox, due elenchi a discesa e un controllo CheckBox (fare clic per visualizzare un'immagine a dimensione intera)

Passaggio 1: Visualizzazione delle informazioni sul prodotto

Prima di poter creare l'interfaccia modificabile di DataList, è prima necessario compilare l'interfaccia di sola lettura. Per iniziare, aprire la CustomizedUI.aspx pagina dalla EditDeleteDataList cartella e, dalla finestra di progettazione, aggiungere un oggetto DataList alla pagina, impostandone la ID proprietà su Products. Dallo smart tag di DataList creare un nuovo ObjectDataSource. Denominare il nuovo ObjectDataSource ProductsDataSource e configurarlo per recuperare i dati dal ProductsBLL metodo della GetProducts classe. Come per le esercitazioni di DataList modificabili precedenti, le informazioni sul prodotto modificate verranno aggiornate passando direttamente al livello della logica di business. Di conseguenza, impostare gli elenchi a discesa nelle schede UPDATE, INSERT e DELETE su (Nessuno).

Impostare gli elenchi a discesa UPDATE, INSERT e DELETE su (Nessuno)

Figura 2: Impostare gli elenchi a discesa UPDATE, INSERT e DELETE su (Nessuno) (Fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver configurato ObjectDataSource, Visual Studio creerà un valore predefinito ItemTemplate per DataList che elenca il nome e il valore per ognuno dei campi dati restituiti. Modificare in ItemTemplate modo che il modello elenchi il nome del prodotto in un <h4> elemento insieme al nome della categoria, al nome del fornitore, al prezzo e allo stato sospeso. Aggiungere inoltre un pulsante Modifica, assicurandosi che la relativa CommandName proprietà sia impostata su Modifica. Il markup dichiarativo per il codice ItemTemplate seguente:

<ItemTemplate>
    <h4>
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' />
    </h4>
    <table border="0">
        <tr>
            <td class="ProductPropertyLabel">Category:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="CategoryNameLabel" runat="server"
                    Text='<%# Eval("CategoryName") %>' />
            </td>
            <td class="ProductPropertyLabel">Supplier:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="SupplierNameLabel" runat="server"
                    Text='<%# Eval("SupplierName") %>' />
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Discontinued:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="DiscontinuedLabel" runat="server"
                    Text='<%# Eval("Discontinued") %>' />
            </td>
            <td class="ProductPropertyLabel">Price:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
            </td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:Button runat="Server" ID="EditButton"
                    Text="Edit" CommandName="Edit" />
            </td>
        </tr>
    </table>
    <br />
</ItemTemplate>

Il markup precedente dispone le informazioni sul prodotto usando un'intestazione <h4> per il nome del prodotto e una quattro colonne <table> per i campi rimanenti. Le ProductPropertyLabel classi CSS e ProductPropertyValue , definite in Styles.css, sono state illustrate nelle esercitazioni precedenti. La figura 3 mostra lo stato di avanzamento quando viene visualizzato tramite un browser.

Viene visualizzato il nome, il fornitore, la categoria, lo stato sospeso e il prezzo di ogni prodotto

Figura 3: Nome, Fornitore, Categoria, Stato sospeso e Prezzo di ogni prodotto viene visualizzato (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 2: Aggiunta dei controlli Web all'interfaccia di modifica

Il primo passaggio per la creazione dell'interfaccia di modifica personalizzata di DataList consiste nell'aggiungere i controlli Web necessari a EditItemTemplate. In particolare, è necessario un Elenco a discesa per la categoria, un altro per il fornitore e un controllo CheckBox per lo stato sospeso. Poiché il prezzo del prodotto non è modificabile in questo esempio, è possibile continuare a visualizzarlo usando un controllo Web Etichetta.

Per personalizzare l'interfaccia di modifica, fare clic sul collegamento Modifica modelli dallo smart tag DataList e scegliere l'opzione EditItemTemplate dall'elenco a discesa. Aggiungere un oggetto DropDownList a EditItemTemplate e impostarlo ID su Categories.

Aggiungere un elenco a discesa per le categorie

Figura 4: Aggiungere un elenco a discesa per le categorie (fare clic per visualizzare l'immagine a dimensione intera)

Successivamente, dallo smart tag DropDownList s selezionare l'opzione Scegli origine dati e creare un nuovo OggettoDataSource denominato CategoriesDataSource. Configurare ObjectDataSource per l'uso del metodo della GetCategories() classe (vedere la CategoriesBLL figura 5). Successivamente, la Configurazione guidata origine dati dropDownList richiede che i campi dati vengano usati per ogni ListItem proprietà Text e Value . Fare in modo che l'elenco a discesa visualizzi il CategoryName campo dati e usi CategoryID come valore, come illustrato nella figura 6.

Creare un nuovo oggettoDataSource denominato CategoriesDataSource

Figura 5: Creare un nuovo oggettoDataSource denominato CategoriesDataSource (fare clic per visualizzare l'immagine a dimensione intera)

Configurare i campi visualizzazione e valore di DropDownList

Figura 6: Configurare i campi visualizzazione e valore dell'elenco a discesa (fare clic per visualizzare l'immagine a dimensione intera)

Ripetere questa serie di passaggi per creare un elenco a discesa per i fornitori. Impostare per l'oggetto ID DropDownList su Suppliers e denominarne ObjectDataSource SuppliersDataSource.

Dopo aver aggiunto i due DropDownLists, aggiungere un controllo CheckBox per lo stato sospeso e un controllo TextBox per il nome del prodotto. Impostare rispettivamente i ID valori per CheckBox e TextBox Discontinued su e ProductName. Aggiungere un oggetto RequiredFieldValidator per assicurarsi che l'utente fornisca un valore per il nome del prodotto.

Infine, aggiungere i pulsanti Aggiorna e Annulla. Tenere presente che per questi due pulsanti è fondamentale che le relative CommandName proprietà siano impostate rispettivamente su Update e Cancel.

È possibile disporre l'interfaccia di modifica, ma si preferisce. Si è scelto di usare lo stesso layout a quattro colonne <table> dall'interfaccia di sola lettura, come illustrato nella sintassi dichiarativa e nello screenshot seguenti:

<EditItemTemplate>
    <h4>
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' />
    </h4>
    <table border="0">
        <tr>
            <td class="ProductPropertyLabel">Name:</td>
            <td colspan="3" class="ProductPropertyValue">
                <asp:TextBox runat="server" ID="ProductName" Width="90%" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
                    ControlToValidate="ProductName"
                    ErrorMessage="You must enter a name for the product."
                    runat="server">*</asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Category:</td>
            <td class="ProductPropertyValue">
                <asp:DropDownList ID="Categories" runat="server"
                    DataSourceID="CategoriesDataSource"
                    DataTextField="CategoryName" DataValueField="CategoryID" />
            </td>
            <td class="ProductPropertyLabel">Supplier:</td>
            <td class="ProductPropertyValue">
                <asp:DropDownList ID="Suppliers" DataTextField="CompanyName"
                    DataSourceID="SuppliersDataSource"
                    DataValueField="SupplierID" runat="server" />
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Discontinued:</td>
            <td class="ProductPropertyValue">
                <asp:CheckBox runat="server" id="Discontinued" />
            </td>
            <td class="ProductPropertyLabel">Price:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
            </td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:Button runat="Server" ID="UpdateButton" CommandName="Update"
                    Text="Update" />
                 
                <asp:Button runat="Server" ID="CancelButton" CommandName="Cancel"
                    Text="Cancel" CausesValidation="False" />
            </td>
        </tr>
    </table>
    <br />
    <asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"
        TypeName="CategoriesBLL">
    </asp:ObjectDataSource>
    <asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers"
        TypeName="SuppliersBLL">
    </asp:ObjectDataSource>
</EditItemTemplate>

L'interfaccia di modifica è disposta come l'interfaccia di sola lettura

Figura 7: L'interfaccia di modifica è disposta come l'interfaccia di sola lettura (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 3: Creazione dei gestori eventi EditCommand e CancelCommand

Attualmente non esiste alcuna sintassi di associazione dati in EditItemTemplate ,ad eccezione di UnitPriceLabel, copiato su verbatim da ItemTemplate. Si aggiungerà momentaneamente la sintassi di associazione dati, ma prima di tutto si creeranno i gestori eventi per gli eventi e CancelCommand gli eventi DataListEditCommand. Tenere presente che la responsabilità del gestore eventi consiste nel eseguire il rendering dell'interfaccia EditCommand di modifica per l'elemento DataList su cui è stato fatto clic sul pulsante Modifica, mentre il CancelCommand processo di s deve restituire DataList allo stato di pre-modifica.

Creare questi due gestori eventi e fare in modo che usino il codice seguente:

protected void Products_EditCommand(object source, DataListCommandEventArgs e)
{
    // Set the DataList's EditItemIndex property and rebind the data
    Products.EditItemIndex = e.Item.ItemIndex;
    Products.DataBind();
}
protected void Products_CancelCommand(object source, DataListCommandEventArgs e)
{
    // Return to DataList to its pre-editing state
    Products.EditItemIndex = -1;
    Products.DataBind();
}

Con questi due gestori eventi sul posto, facendo clic sul pulsante Modifica viene visualizzata l'interfaccia di modifica e facendo clic sul pulsante Annulla viene restituito l'elemento modificato alla modalità di sola lettura. La figura 8 mostra datalist dopo che è stato fatto clic sul pulsante Modifica per Chef Anton s Gumbo Mix. Poiché è ancora stato aggiunto qualsiasi sintassi di associazione dati all'interfaccia di modifica, TextBox ProductName è vuoto, Discontinued CheckBox deselezionato e i primi elementi selezionati dagli Categories elenchi a discesa e Suppliers .

Screenshot che mostra DataList EditItemTemplate dopo l'aggiunta dei gestori eventi EditCommand e CancelCommand e il pulsante Modifica è stato selezionato.

Figura 8: Facendo clic sul pulsante Modifica viene visualizzata l'interfaccia di modifica (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 4: Aggiunta della sintassi DataBinding all'interfaccia di modifica

Per fare in modo che l'interfaccia di modifica visualizzi i valori correnti del prodotto, è necessario usare la sintassi di associazione dati per assegnare i valori dei campi dati ai valori di controllo Web appropriati. La sintassi di associazione dati può essere applicata tramite la finestra di progettazione passando alla schermata Modifica modelli e selezionando il collegamento Modifica dataBinding dai controlli Web smart tag. In alternativa, la sintassi di associazione dati può essere aggiunta direttamente al markup dichiarativo.

Assegnare il valore del ProductName campo dati alla ProductName proprietà TextBox s Text , i valori dei CategoryID campi dati e SupplierID alle Categories proprietà e Suppliers DropDownLists SelectedValue e il valore del Discontinued campo dati alla Discontinued proprietà CheckBox s Checked . Dopo aver apportato queste modifiche, tramite la finestra di progettazione o direttamente tramite il markup dichiarativo, rivedere la pagina tramite un browser e fare clic sul pulsante Modifica per Chef Anton s Gumbo Mix. Come illustrato nella figura 9, la sintassi di associazione dati ha aggiunto i valori correnti in TextBox, DropDownLists e CheckBox.

Screenshot che mostra l'oggetto DataList EditItemTemplate dopo l'aggiunta della sintassi DataBinding e il pulsante Modifica è stato selezionato.

Figura 9: Facendo clic sul pulsante Modifica viene visualizzata l'interfaccia di modifica (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 5: Salvataggio delle modifiche dell'utente nel gestore eventi UpdateCommand

Quando l'utente modifica un prodotto e fa clic sul pulsante Aggiorna, viene generato un postback e viene generato l'evento datalist UpdateCommand . Nel gestore eventi è necessario leggere i valori dai controlli Web nell'interfaccia EditItemTemplate e con il BLL per aggiornare il prodotto nel database. Come abbiamo visto nelle esercitazioni precedenti, il ProductID del prodotto aggiornato è accessibile tramite la DataKeys raccolta. I campi immessi dall'utente sono accessibili facendo riferimento a livello di codice ai controlli Web tramite FindControl("controlID"), come illustrato nel codice seguente:

protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
    // Make sure the page is valid...
    if (!Page.IsValid)
        return;
    // Read in the ProductID from the DataKeys collection
    int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
    // Read in the product name and price values
    TextBox productName = (TextBox)e.Item.FindControl("ProductName");
    DropDownList categories = (DropDownList)e.Item.FindControl("Categories");
    DropDownList suppliers = (DropDownList)e.Item.FindControl("Suppliers");
    CheckBox discontinued = (CheckBox)e.Item.FindControl("Discontinued");
    string productNameValue = null;
    if (productName.Text.Trim().Length > 0)
        productNameValue = productName.Text.Trim();
    int categoryIDValue = Convert.ToInt32(categories.SelectedValue);
    int supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
    bool discontinuedValue = discontinued.Checked;
    // Call the ProductsBLL's UpdateProduct method...
    ProductsBLL productsAPI = new ProductsBLL();
    productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue,
                              discontinuedValue, productID);
    // Revert the DataList back to its pre-editing state
    Products.EditItemIndex = -1;
    Products.DataBind();
}

Il codice inizia consultando la Page.IsValid proprietà per assicurarsi che tutti i controlli di convalida nella pagina siano validi. Se Page.IsValid è True, il valore del ProductID prodotto modificato viene letto dalla DataKeys raccolta e viene fatto riferimento ai controlli Web di immissione dei dati in EditItemTemplate a livello di codice. Successivamente, i valori di questi controlli Web vengono letti in variabili che vengono quindi passate all'overload appropriato UpdateProduct . Dopo l'aggiornamento dei dati, DataList viene restituito allo stato di pre-modifica.

Nota

È stata omessa la logica di gestione delle eccezioni aggiunta nell'esercitazione Sulla gestione delle eccezioni BLL e DAL-Level per mantenere attivo il codice e questo esempio. Come esercizio, aggiungere questa funzionalità dopo aver completato questa esercitazione.

Passaggio 6: Gestione dei valori CategoryID NULL e SupplierID

Il database Northwind consente valori NULL per le colonne e SupplierID della Products tabellaCategoryID. Tuttavia, l'interfaccia di modifica attualmente non supporta NULL i valori. Se si tenta di modificare un prodotto con un NULL valore per le colonne CategoryID o , SupplierID verrà visualizzato un ArgumentOutOfRangeException messaggio di errore simile al seguente: 'Categories' ha un selectedValue non valido perché non esiste nell'elenco di elementi. Inoltre, attualmente non è possibile modificare la categoria di un prodotto o il valore del fornitore da un valore diversoNULL da un valore a uno NULL .

Per supportare NULL i valori per la categoria e i fornitori DropDownLists, è necessario aggiungere un altro ListItemoggetto . Ho scelto di usare (Nessuno) come Text valore per questo ListItem, ma è possibile modificarlo in qualcos'altro (ad esempio una stringa vuota) se si vuole. Infine, ricordarsi di impostare DropDownLists AppendDataBoundItems su True. Se si dimentica di farlo, le categorie e i fornitori associati a DropDownList sovrascriveranno l'oggetto aggiunto ListItemin modo statico.

Dopo aver apportato queste modifiche, il markup DropDownLists in DataList s EditItemTemplate dovrebbe essere simile al seguente:

<asp:DropDownList ID="Categories" DataSourceID="CategoriesDataSource"
    DataTextField="CategoryName" DataValueField="CategoryID" runat="server"
    SelectedValue='<%# Eval("CategoryID") %>' AppendDataBoundItems="True">
    <asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
...
<asp:DropDownList ID="Suppliers" DataSourceID="SuppliersDataSource"
    DataTextField="CompanyName" DataValueField="SupplierID" runat="server"
    SelectedValue='<%# Eval("SupplierID") %>' AppendDataBoundItems="True">
    <asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>

Nota

Gli elementi statici ListItem possono essere aggiunti a un oggetto DropDownList tramite la finestra di progettazione o direttamente tramite la sintassi dichiarativa. Quando si aggiunge un elemento DropDownList per rappresentare un valore di database NULL , assicurarsi di aggiungere tramite ListItem la sintassi dichiarativa. Se si usa l'editor ListItem di raccolte in Progettazione, la sintassi dichiarativa generata ometterà completamente l'impostazione Value quando viene assegnata una stringa vuota, creando markup dichiarativo come : <asp:ListItem>(None)</asp:ListItem>. Anche se questo può sembrare innocuo, l'elemento mancante Value fa sì che DropDownList usi il valore della Text proprietà al suo posto. Ciò significa che, se questa NULL ListItem opzione è selezionata, il valore (Nessuno) verrà provato ad essere assegnato al campo dati del prodotto (CategoryID o SupplierID, in questa esercitazione), che genererà un'eccezione. Impostando Value=""in modo esplicito , un NULL valore verrà assegnato al campo dati del prodotto quando NULL ListItem viene selezionato .

Per visualizzare lo stato di avanzamento, passare da un browser. Quando si modifica un prodotto, si noti che e Categories Suppliers DropDownLists hanno entrambe un'opzione (Nessuna) all'inizio dell'elenco a discesa.

Gli elenchi a discesa Categorie e Fornitori includono un'opzione (Nessuna)

Figura 10: Gli Categories elenchi a discesa e Suppliers includono un'opzione (Nessuno) (Fare clic per visualizzare l'immagine a dimensione intera)

Per salvare l'opzione (Nessuna) come valore del database NULL , è necessario tornare al UpdateCommand gestore eventi. Modificare le categoryIDValue variabili e supplierIDValue in modo che siano numeri interi nullable e assegnarli un valore diverso Nothing da solo se dropDownList s SelectedValue non è una stringa vuota:

int? categoryIDValue = null;
if (!string.IsNullOrEmpty(categories.SelectedValue))
    categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int? supplierIDValue = null;
if (!string.IsNullOrEmpty(suppliers.SelectedValue))
    supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);

Con questa modifica, un valore di Nothing verrà passato al UpdateProduct metodo BLL se l'utente ha selezionato l'opzione (Nessuno) da uno degli elenchi a discesa, che corrisponde a un NULL valore del database.

Riepilogo

In questa esercitazione è stato illustrato come creare un'interfaccia di modifica DataList più complessa che include tre diversi controlli Web di input un controllo TextBox, due DropDownList e un controllo CheckBox insieme ai controlli di convalida. Quando si compila l'interfaccia di modifica, i passaggi sono gli stessi indipendentemente dai controlli Web utilizzati: iniziare aggiungendo i controlli Web a DataList s EditItemTemplate; utilizzare la sintassi di associazione dati per assegnare i valori dei campi dati corrispondenti con le proprietà del controllo Web appropriate; e, nel UpdateCommand gestore eventi, accedere a livello di codice ai controlli Web e alle relative proprietà appropriate. passando i valori nel BLL.

Quando si crea un'interfaccia di modifica, indipendentemente dal fatto che sia costituita solo da TextBoxes o da una raccolta di controlli Web diversi, assicurarsi di gestire correttamente i valori del database NULL . Quando si considerano NULL s, è fondamentale non solo visualizzare correttamente un valore esistente NULL nell'interfaccia di modifica, ma anche che si offre un mezzo per contrassegnare un valore come NULL. Per DropDownLists in DataLists, che in genere indica l'aggiunta di una proprietà statica la cui proprietà è impostata ListItem in modo esplicito su una stringa vuota (Value="") e l'aggiunta di un bit di codice al UpdateCommand gestore eventi per determinare se è stato selezionato o meno NULL``ListItem .Value

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato 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, che può essere trovato all'indirizzo http://ScottOnWriting.NET.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori potenziali per questa esercitazione sono stati Dennis Patterson, David Suru e Randy Schmidt. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciarmi una riga in mitchell@4GuysFromRolla.com.