Personalizzazione dell'interfaccia di modifica di DataList (VB)
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:
- Aggiungere il controllo Web a
EditItemTemplate
. - Utilizzare la sintassi di associazione dati per assegnare il valore del campo dati corrispondente alla proprietà appropriata.
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).
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).
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.
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
.
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.
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 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"
DataSourceID="SuppliersDataSource" DataTextField="CompanyName"
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
. 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 Sub Products_EditCommand(source As Object, e As DataListCommandEventArgs) _
Handles Products.EditCommand
' Set the DataList's EditItemIndex property to the
' index of the DataListItem that was clicked
Products.EditItemIndex = e.Item.ItemIndex
' Rebind the data to the DataList
Products.DataBind()
End Sub
Protected Sub Products_CancelCommand(source As Object, e As DataListCommandEventArgs) _
Handles Products.CancelCommand
' Set the DataList's EditItemIndex property to -1
Products.EditItemIndex = -1
' Rebind the data to the DataList
Products.DataBind()
End Sub
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
.
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.
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 Sub Products_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
Handles Products.UpdateCommand
If Not Page.IsValid Then
Exit Sub
End If
' Read in the ProductID from the DataKeys collection
Dim productID As Integer = Convert.ToInt32(Products.DataKeys(e.Item.ItemIndex))
' Read in the product name and price values
Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
Dim categories As DropDownList=CType(e.Item.FindControl("Categories"), DropDownList)
Dim suppliers As DropDownList = CType(e.Item.FindControl("Suppliers"), DropDownList)
Dim discontinued As CheckBox = CType(e.Item.FindControl("Discontinued"), CheckBox)
Dim productNameValue As String = Nothing
If productName.Text.Trim().Length > 0 Then
productNameValue = productName.Text.Trim()
End If
Dim categoryIDValue As Integer = Convert.ToInt32(categories.SelectedValue)
Dim supplierIDValue As Integer = Convert.ToInt32(suppliers.SelectedValue)
Dim discontinuedValue As Boolean = discontinued.Checked
' Call the ProductsBLL's UpdateProduct method...
Dim productsAPI As New ProductsBLL()
productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue, _
discontinuedValue, productID)
' Revert the DataList back to its pre-editing state
Products.EditItemIndex = -1
Products.DataBind()
End Sub
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 ListItem
oggetto . 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 ListItem
in 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.
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:
Dim categoryIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(categories.SelectedValue) Then
categoryIDValue = Convert.ToInt32(categories.SelectedValue)
End If
Dim supplierIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(suppliers.SelectedValue) Then
supplierIDValue = Convert.ToInt32(suppliers.SelectedValue)
End If
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.