Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In questa esercitazione verrà creata un'interfaccia di modifica più completa per DataList, una che include DropDownLists e checkBox.
Introduzione
I controlli Web e il markup in DataList EditItemTemplate definiscono la sua interfaccia modificabile. In tutti gli esempi di DataList modificabili esaminati finora, l'interfaccia modificabile è costituita da controlli Web TextBox. Nella precedente esercitazione, abbiamo migliorato l'esperienza utente durante la 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:
- Aggiungere il controllo Web a
EditItemTemplate. - Utilizzare la sintassi di associazione dati per assegnare il valore del campo dati corrispondente alla proprietà appropriata.
- Nel gestore eventi
UpdateCommand, accedere programmaticamente 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).
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 questo nuovo ObjectDataSource ProductsDataSource e configurarlo per recuperare i dati dal metodo della classe ProductsBLLGetProducts. 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).
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. Modifica il ItemTemplate in modo che il modello elenchi il nome del prodotto in un elemento <h4> insieme al nome della categoria, al nome del fornitore, al prezzo e allo stato di discontinuità. Aggiungere inoltre un pulsante Modifica, assicurandosi che la relativa CommandName proprietà sia impostata su Modifica. Il markup dichiarativo per il mio ItemTemplate è il 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.
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 menu a discesa per la categoria, un altro per il fornitore e una casella di controllo 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.
Figura 4: Aggiungere un elenco a discesa per le categorie (fare clic per visualizzare l'immagine a dimensione intera)
Successivamente, dallo smart tag di DropDownList, selezionare l'opzione Scegli origine dati e creare un nuovo ObjectDataSource denominato CategoriesDataSource. Configurare ObjectDataSource per usare la classe CategoriesBLL metodo GetCategories() (vedere figura 5). Successivamente, la Configurazione guidata origine dati della DropDownList richiede i campi dati da utilizzare per ogni proprietà ListItem, 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.
Figura 5: Creare un nuovo oggettoDataSource denominato CategoriesDataSource (fare clic per visualizzare l'immagine a dimensione intera)
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 il ID per questo DropDownList su Suppliers e nominare il suo ObjectDataSource SuppliersDataSource.
Dopo aver aggiunto le due liste a discesa, aggiungere una casella di controllo (CheckBox) per lo stato interrotto e una casella di testo (TextBox) per il nome del prodotto. Imposta il ID per il CheckBox su Discontinued e il TextBox su ProductName, rispettivamente. Aggiungere un oggetto "RequiredFieldValidator" per assicurare 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 come preferisci. 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>
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. Aggiungeremo presto la sintassi di associazione dati, ma prima dobbiamo creare i gestori eventi per gli eventi di EditCommand e CancelCommand di DataList. Tenere presente che la responsabilità del gestore eventi consiste nell'eseguire il rendering dell'interfaccia di modifica per l'elemento DataList EditCommand, su cui è stato fatto clic sul pulsante Modifica, mentre il compito del gestore CancelCommand è riportare il DataList allo stato di pre-modifica.
Creare questi due gestori di eventi affinché utilizzino 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 la DataList dopo che è stato fatto clic sul pulsante Modifica per Chef Anton's Gumbo Mix. Poiché non è stata ancora aggiunta alcuna sintassi di associazione dati all'interfaccia di modifica, il TextBox ProductName è vuoto, il CheckBox Discontinued è deselezionato, e i primi elementi sono selezionati dagli elenchi a discesa Categories e Suppliers.
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 accedendo alla schermata di modifica modelli e cliccando sul link Modifica DataBindings dalle etichette intelligenti dei controlli Web. In alternativa, la sintassi di associazione dati può essere aggiunta direttamente al markup dichiarativo.
Assegnare il valore del ProductName campo dati alla proprietà ProductName del TextBoxText, i valori dei CategoryID e SupplierID campi dati alle proprietà Categories e Suppliers dei DropDownListSelectedValue, e il valore del Discontinued campo dati alla proprietà Discontinued del CheckBoxChecked. 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.
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 si attiva l'evento DataList UpdateCommand. Nel gestore eventi, è necessario leggere i valori dai controlli Web nel EditItemTemplate e interfacciarsi con il BLL per aggiornare i dati del 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 modificato di ProductID viene letto dalla raccolta DataKeys e i controlli Web per l'immissione dei dati in EditItemTemplate vengono riferiti 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 a livello BLL e DAL per mantenere il codice e questo esempio focalizzati. 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 SupplierID e CategoryID della tabella Products. Tuttavia, l'interfaccia di modifica attualmente non supporta NULL i valori. Se cerchiamo di modificare un prodotto che ha un valore NULL per le colonne CategoryID o SupplierID, verrà visualizzato un messaggio di errore ArgumentOutOfRangeException 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 non-NULL a uno NULL.
Per supportare NULL i valori per il menu a tendina della categoria e del fornitore, è necessario aggiungere un altro ListItem. 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 aggiungerlo tramite la sintassi dichiarativa ListItem. 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 NULLListItem 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 NULLListItem viene selezionato .
Prenditi un momento per dare un'occhiata ai nostri progressi attraverso un browser. Quando si modifica un prodotto, si noti che e CategoriesSuppliers DropDownLists hanno entrambe un'opzione (Nessuna) all'inizio dell'elenco a discesa.
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 variabili categoryIDValue e supplierIDValue per essere numeri interi annullabili e assegnare loro un valore diverso da Nothing solo se la DropDownList 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, è imperativo non solo visualizzare correttamente un valore esistente NULL nell'interfaccia di modifica, ma anche offrire un mezzo per contrassegnare un valore come NULL. Nelle DropDownList nei DataList, questo di solito significa l'aggiunta di un elemento statico ListItem la cui proprietà Value è impostata esplicitamente su una stringa vuota (Value=""), e l'aggiunta di un po' di codice al gestore eventi UpdateCommand per determinare se NULL``ListItem è stato selezionato o meno.
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 a mitchell@4GuysFromRolla.com.
Grazie speciale a
Questa serie di esercitazioni è stata esaminata da diversi revisori validi. I revisori principali per questa esercitazione erano Dennis Patterson, David Suru e Randy Schmidt. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.