Personalizzazione dell'interfaccia di modifica dei dati (C#)

di Scott Mitchell

Scarica il PDF

In questa esercitazione verrà illustrato come personalizzare l'interfaccia di un controllo GridView modificabile sostituendo i controlli TextBox e CheckBox standard con controlli Web di input alternativi.

Introduzione

I controlli BoundFields e CheckBoxField usati dai controlli GridView e DetailsView semplificano il processo di modifica dei dati a causa della possibilità di eseguire il rendering di interfacce di sola lettura, modificabili e inseriscibili. Queste interfacce possono essere sottoposte a rendering senza la necessità di aggiungere alcun markup dichiarativo o codice aggiuntivo. Tuttavia, le interfacce di BoundField e CheckBoxField non hanno la personalizzazione spesso necessaria negli scenari reali. Per personalizzare l'interfaccia modificabile o inseriscibile in un oggetto GridView o DetailsView, è necessario usare invece un ModelloField.

Nell'esercitazione precedente è stato illustrato come personalizzare le interfacce di modifica dei dati aggiungendo controlli Web di convalida. In questa esercitazione verrà illustrato come personalizzare i controlli Web di raccolta dati effettivi, sostituendo i controlli TextBox standard di BoundField e CheckBoxField con controlli Web di input alternativi. In particolare, si creerà un controllo GridView modificabile che consente l'aggiornamento dello stato aggiornato del nome, della categoria, del fornitore e dell'interruzione di un prodotto. Quando si modifica una determinata riga, i campi categoria e fornitore verranno visualizzati come DropDownList, contenente il set di categorie e fornitori disponibili da scegliere. Inoltre, si sostituirà checkbox predefinito di CheckBoxField con un controllo RadioButtonList che offre due opzioni: "Active" e "Discontinued".

L'interfaccia di modifica di GridView include DropDownLists e RadioButtons

Figura 1: L'interfaccia di modifica di GridView include DropDownLists e RadioButtons (Fare clic per visualizzare l'immagine full-size)

Passaggio 1: Creazione dell'overload appropriatoUpdateProduct

In questa esercitazione verrà creato un controllo GridView modificabile che consente di modificare il nome, la categoria, il fornitore e lo stato interrotto di un prodotto. Pertanto, è necessario un UpdateProduct overload che accetta cinque parametri di input questi quattro valori del prodotto più .ProductID Come negli overload precedenti, questa operazione:

  1. Recuperare le informazioni sul prodotto dal database per l'oggetto specificato ProductID,
  2. Aggiornare i ProductNamecampi , CategoryIDSupplierID, e Discontinued e
  3. Inviare la richiesta di aggiornamento al dal tramite il metodo TableAdapter Update() .

Per brevità, per questo particolare overload ho omesso il controllo della regola aziendale che garantisce che un prodotto contrassegnato come interrotto non sia l'unico prodotto offerto dal suo fornitore. È possibile aggiungerlo se si preferisce o, idealmente, eseguire il refactoring della logica in un metodo separato.

Il codice seguente mostra il nuovo UpdateProduct overload nella ProductsBLL classe:

[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, int? categoryID,
    int? supplierID, bool discontinued, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    product.ProductName = productName;
    if (supplierID == null) product.SetSupplierIDNull();
      else product.SupplierID = supplierID.Value;
    if (categoryID == null) product.SetCategoryIDNull();
      else product.CategoryID = categoryID.Value;
    product.Discontinued = discontinued;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Passaggio 2: Creazione di GridView modificabile

Con l'overload UpdateProduct aggiunto, è possibile creare GridView modificabile. Aprire la CustomizedUI.aspx pagina nella EditInsertDelete cartella e aggiungere un controllo GridView al Designer. Creare quindi un nuovo oggetto ObjectDataSource dallo smart tag di GridView. Configurare ObjectDataSource per recuperare le informazioni sul prodotto tramite il ProductBLL metodo della classe e aggiornare i dati del GetProducts() prodotto usando l'overload UpdateProduct appena creato. Nelle schede INSERT e DELETE selezionare (Nessuno) negli elenchi a discesa.

Configurare ObjectDataSource per usare l'overload UpdateProduct appena creato

Figura 2: Configurare ObjectDataSource per usare l'overload appena creato (fare clic per visualizzare l'immagineUpdateProduct full-size)

Come illustrato nelle esercitazioni sulla modifica dei dati, la sintassi dichiarativa per ObjectDataSource creata da Visual Studio assegna la OldValuesParameterFormatString proprietà a original_{0}. Questo, naturalmente, non funzionerà con il livello di logica di business perché i metodi non prevedono che il valore originale ProductID venga passato. Pertanto, come abbiamo fatto nelle esercitazioni precedenti, richiedere un momento per rimuovere questa assegnazione di proprietà dalla sintassi dichiarativa o, invece, impostare il valore di questa proprietà su {0}.

Dopo questa modifica, il markup dichiarativo di ObjectDataSource dovrebbe essere simile al seguente:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Si noti che la OldValuesParameterFormatString proprietà è stata rimossa e che nella raccolta è presente un Parameter oggetto per ognuno dei parametri di input previsti dall'overload UpdateParametersUpdateProduct .

Sebbene ObjectDataSource sia configurato per aggiornare solo un subset di valori del prodotto, GridView visualizza attualmente tutti i campi del prodotto. Modificare GridView in modo che:

  • Include solo , ProductNameBoundFields CategoryNameSupplierNamee Discontinued CheckBoxField
  • I CategoryName campi e SupplierName da visualizzare prima (a sinistra) di Discontinued CheckBoxField
  • La CategoryName proprietà e SupplierName BoundFields HeaderText è impostata rispettivamente su "Category" e "Supplier", rispettivamente
  • Il supporto di modifica è abilitato (selezionare la casella di controllo Abilita modifica nel smart tag gridView)

Dopo queste modifiche, la Designer sarà simile alla figura 3, con la sintassi dichiarativa di GridView illustrata di seguito.

Rimuovere i campi non autorizzati da GridView

Figura 3: Rimuovere i campi non utilizzati da GridView (Fare clic per visualizzare l'immagine a dimensioni complete)

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:BoundField DataField="ProductName"
           HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
           ReadOnly="True"
           SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier"
           ReadOnly="True"
           SortExpression="SupplierName" />
        <asp:CheckBoxField DataField="Discontinued"
           HeaderText="Discontinued" SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

A questo punto viene completato il comportamento di sola lettura di GridView. Quando si visualizzano i dati, ogni prodotto viene eseguito come riga in GridView, che mostra il nome, la categoria, il fornitore e lo stato interrotto del prodotto.

L'interfaccia Read-Only di GridView è completa

Figura 4: l'interfaccia Read-Only di GridView è completa (fare clic per visualizzare l'immagine a dimensioni complete)

Nota

Come illustrato in Panoramica dell'inserimento, dell'aggiornamento e dell'eliminazione dei dati, è importante abilitare lo stato di visualizzazione di GridView (comportamento predefinito). Se si imposta la proprietà falseGridView su EnableViewState , si rischia di avere utenti simultanei che eliminano o modificano i record in modo imprevisto.

Passaggio 3: Uso di un elenco a discesa per le interfacce di modifica categoria e fornitore

Si noti che l'oggetto ProductsRow contiene proprietà , CategoryName, SupplierIDeSupplierName, che forniscono i valori id chiave esterna effettivi nella tabella di database e i valori corrispondenti Name nelle ProductsCategories tabelle e SuppliersCategoryID. L'oggetto ProductRowCategoryID e SupplierID può essere letto da e scritto in, mentre le CategoryName proprietà e SupplierName sono contrassegnate in sola lettura.

A causa dello stato di sola lettura delle CategoryName proprietà e SupplierName , i corrispondenti BoundFields hanno avuto la proprietà ReadOnly impostata su true, impedendo che questi valori vengano modificati quando viene modificata una riga. Anche se è possibile impostare la proprietà su false, eseguire il ReadOnly rendering di CategoryName e SupplierName BoundFields come TextBoxes durante la modifica, tale approccio comporterà un'eccezione quando l'utente tenta di aggiornare il prodotto poiché non UpdateProduct è presente alcun overload che accetta CategoryName e SupplierName input. Infatti, non si vuole creare un overload di questo tipo per due motivi:

  • La Products tabella non include SupplierName o CategoryName campi, ma SupplierID e CategoryID. Pertanto, si vuole che il metodo venga passato questi valori ID specifici, non i valori delle tabelle di ricerca.
  • Richiedere all'utente di digitare il nome del fornitore o della categoria è minore dell'ideale, perché richiede all'utente di conoscere le categorie e i fornitori disponibili e le relative ortografie corrette.

I campi fornitore e categoria devono visualizzare i nomi delle categorie e dei fornitori quando in modalità di sola lettura (come è ora) e un elenco a discesa delle opzioni applicabili quando viene modificato. Usando un elenco a discesa, l'utente finale può visualizzare rapidamente quali categorie e fornitori sono disponibili per scegliere e può rendere più facilmente la propria selezione.

Per fornire questo comportamento, è necessario convertire e SupplierName BoundFields in TemplateFields i cui genera i SupplierName valori e CategoryNameCategoryName e i cui EditItemTemplateItemTemplate usa un controllo DropDownList per elencare le categorie e i fornitori disponibili.

Aggiunta diCategorieseSuppliersDropDownList

Iniziare convertendo i SupplierName file e CategoryName BoundFields in TemplateFields facendo clic sul collegamento Modifica colonne dal smart tag di GridView, selezionando BoundField dall'elenco in basso a sinistra e facendo clic sul collegamento "Converti questo campo in un campo TemplateField". Il processo di conversione creerà un oggetto TemplateField con sia un EditItemTemplateoggetto ItemTemplate e , come illustrato nella sintassi dichiarativa seguente:

<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
    <EditItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Eval("CategoryName") %>'></asp:Label>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("CategoryName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Poiché BoundField è stato contrassegnato come di sola lettura, sia il ItemTemplate che EditItemTemplate contengono un controllo Web Label la cui Text proprietà è associata al campo dati applicabile (CategoryNamenella sintassi precedente). È necessario modificare , sostituendo il EditItemTemplatecontrollo Web Etichetta con un controllo DropDownList.

Come si è visto nelle esercitazioni precedenti, il modello può essere modificato tramite la Designer o direttamente dalla sintassi dichiarativa. Per modificarlo tramite il Designer, fare clic sul collegamento Modifica modelli dallo smart tag di GridView e scegliere di lavorare con il campo Categoria.EditItemTemplate Rimuovere il controllo Web Etichetta e sostituirlo con un controllo DropDownList, impostando la proprietà ID di DropDownList su Categories.

Rimuovere TexBox e Aggiungere un elenco a discesa all'oggetto EditItemTemplate

Figura 5: Rimuovere TexBox e Aggiungere un elenco a discesa all'oggetto EditItemTemplate (Fare clic per visualizzare l'immagine full-size)

Sarà quindi necessario popolare DropDownList con le categorie disponibili. Fare clic sul collegamento Scegli origine dati dal smart tag dropDownList e scegliere di creare un nuovo oggetto ObjectDataSource denominato CategoriesDataSource.

Creare un nuovo controllo ObjectDataSource denominato CategoriesDataSource

Figura 6: Creare un nuovo controllo ObjectDataSource denominato CategoriesDataSource (Fare clic per visualizzare l'immagine a dimensioni complete)

Per avere questo oggetto ObjectDataSource restituire tutte le categorie, associarlo al CategoriesBLL metodo della GetCategories() classe.

Associare ObjectDataSource al metodo GetCategories() di CategoriesBLL

Figura 7: Associare ObjectDataSource al CategoriesBLLmetodo 's GetCategories() (Fare clic per visualizzare l'immagine full-size)

Infine, configurare le impostazioni di DropDownList in modo che il CategoryName campo venga visualizzato in ogni DropDownList ListItem con il CategoryID campo usato come valore.

Visualizzare il campo CategoryName e l'ID categoria usato come valore

Figura 8: visualizzare il campo e l'oggetto CategoryID Usato come valore (fare clic per visualizzare l'immagineCategoryName a dimensioni complete)

Dopo aver apportato queste modifiche, il markup dichiarativo per in EditItemTemplateCategoryName TemplateField includerà sia un DropDownList che un OggettoDataSource:

<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
    <EditItemTemplate>
        <asp:DropDownList ID="Categories" runat="server"
          DataSourceID="CategoriesDataSource"
          DataTextField="CategoryName" DataValueField="CategoryID">
        </asp:DropDownList>
        <asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
            OldValuesParameterFormatString="original_{0}"
            SelectMethod="GetCategories" TypeName="CategoriesBLL">
        </asp:ObjectDataSource>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("CategoryName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Nota

DropDownList nell'oggetto EditItemTemplate deve avere lo stato di visualizzazione abilitato. Verrà presto aggiunta la sintassi databinding alla sintassi dichiarativa di DropDownList e ai comandi di databinding come Eval() e Bind() possono essere visualizzati solo nei controlli il cui stato di visualizzazione è abilitato.

Ripetere questi passaggi per aggiungere un elenco DropDownList denominato Suppliers all'oggetto SupplierName TemplateField.EditItemTemplate Ciò comporta l'aggiunta di un elenco a discesa all'oggetto EditItemTemplate e la creazione di un altro oggetto ObjectDataSource. L'oggetto Suppliers ObjectDataSource di DropDownList, tuttavia, deve essere configurato per richiamare il SuppliersBLL metodo della GetSuppliers() classe. Configurare inoltre DropDownList per visualizzare Suppliers il campo e usare il CompanyNameSupplierID campo come valore per il relativo ListItem .

Dopo aver aggiunto DropDownLists ai due EditItemTemplate , caricare la pagina in un browser e fare clic sul pulsante Modifica per il prodotto Cajun Seasoning di Chef Anton. Come illustrato nella figura 9, le colonne della categoria e del fornitore del prodotto vengono visualizzate come elenchi a discesa contenenti le categorie e i fornitori disponibili da scegliere. Tuttavia, si noti che i primi elementi in entrambi gli elenchi a discesa sono selezionati per impostazione predefinita (bevande per la categoria e liquid esotici come fornitore), anche se Chef Anton's Cajun Seasoning è un condimento fornito da New Orleans Cajun Delights.

Il primo elemento nella Drop-Down Elenchi è selezionato per impostazione predefinita

Figura 9: Il primo elemento nel Drop-Down Elenchi è selezionato per impostazione predefinita (fare clic per visualizzare l'immagine a dimensione intera)

Inoltre, se si fa clic su Aggiorna, si noterà che i valori e SupplierID del CategoryID prodotto sono impostati su NULL. Entrambi questi comportamenti indesiderati sono causati dal fatto che gli elenchi DropDownList in EditItemTemplate s non sono associati ad alcun campo dati dai dati di prodotto sottostanti.

Associazione degli elenchi a discesa aiCategoryIDcampi dati eSupplierID

Per fare in modo che gli elenchi a discesa categoria e fornitore modificati del prodotto siano impostati sui valori appropriati e che questi valori vengano restituiti al metodo BLL UpdateProduct facendo clic su Aggiorna, è necessario associare le proprietà dropDownLists SelectedValue ai CategoryID campi dati e SupplierID utilizzando il databinding bidirezionale. A tale scopo, è possibile aggiungere SelectedValue='<%# Bind("CategoryID") %>' direttamente alla sintassi dichiarativa l'oggetto Categories DropDownList.

In alternativa, è possibile impostare i databinding di DropDownList modificando il modello tramite il Designer e facendo clic sul collegamento Modifica DataBindings dallo smart tag dropDownList. Indicare quindi che la SelectedValue proprietà deve essere associata al campo usando il CategoryID databinding bidirezionale (vedere la figura 10). Ripetere il processo dichiarativo o Designer per associare il SupplierID campo dati a Suppliers DropDownList.

Associare CategoryID alla proprietà SelectedValue di DropDownList utilizzando Two-Way Databinding

Figura 10: Associare l'oggetto CategoryID alla proprietà di SelectedValue DropDownList usando Two-Way Databinding (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver applicato le associazioni alle SelectedValue proprietà dei due DropDownList, per impostazione predefinita le colonne della categoria e del fornitore del prodotto modificate verranno applicate ai valori del prodotto corrente. Facendo clic su Aggiorna, i CategoryID valori e SupplierID dell'elemento elenco a discesa selezionato verranno passati al UpdateProduct metodo . La figura 11 mostra l'esercitazione dopo l'aggiunta delle istruzioni databinding; si noti come le voci di elenco a discesa selezionate per Chef Anton's Cajun Seasoning sono correttamente Condiment e New Orleans Cajun Delights.

I valori correnti di categoria e fornitore del prodotto modificato sono selezionati per impostazione predefinita

Figura 11: La categoria corrente e i valori fornitore del prodotto modificato sono selezionati per impostazione predefinita (fare clic per visualizzare l'immagine a dimensione intera)

Gestione deiNULLvalori

Le CategoryID colonne e SupplierID nella Products tabella possono essere NULL, ma dropDownLists in EditItemTemplate non includono un elemento elenco per rappresentare un NULL valore. Ciò ha due conseguenze:

  • L'utente non può usare l'interfaccia per modificare la categoria o il fornitore di un prodotto da un valore diversoNULL a uno NULL
  • Se un prodotto ha o NULLCategoryIDSupplierID, facendo clic sul pulsante Modifica verrà generata un'eccezione. Ciò avviene perché il NULL valore restituito da CategoryID (o SupplierID) nell'istruzione non esegue il Bind() mapping a un valore nell'elenco DropDownList( l'oggetto DropDownList genera un'eccezione quando la relativa SelectedValue proprietà è impostata su un valore non incluso nell'insieme di elementi dell'elenco).

Per supportare e i valori, è necessario aggiungere un altro ListItem a ogni DropDownList per rappresentare il NULL valore.SupplierIDNULLCategoryID Nell'esercitazione Filtro master/dettaglio con un oggetto DropDownList è stato illustrato come aggiungere un altro ListItem oggetto a un oggetto DropDownList associato a dati, che implicava l'impostazione della proprietà di AppendDataBoundItems DropDownList su true e l'aggiunta manuale dell'oggetto aggiuntivo ListItem. In questa esercitazione precedente, tuttavia, è stato aggiunto un ListItem oggetto con un Value di -1. La logica di associazione dati in ASP.NET, tuttavia, convertirà automaticamente una stringa vuota in un NULL valore e viceversa. Pertanto, per questa esercitazione si vuole che l'oggetto ListItemValue sia una stringa vuota.

Per iniziare, impostare entrambe le proprietà DropDownLists AppendDataBoundItems su true. Aggiungere quindi l'elemento NULLListItem aggiungendo l'elemento seguente <asp:ListItem> a ogni DropDownList in modo che il markup dichiarativo sia simile al seguente:

<asp:DropDownList ID="Categories" runat="server"
    DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
    DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
    AppendDataBoundItems="True">
    <asp:ListItem Value="">(None)</asp:ListItem>
</asp:DropDownList>

Ho scelto di usare "(None)" come valore text per questo ListItem, ma è possibile modificarlo in modo che sia anche una stringa vuota se si vuole.

Nota

Come illustrato nell'esercitazione Filtro master/dettaglio con un oggetto DropDownList, ListItem è possibile aggiungere s a un oggetto DropDownList tramite il Designer facendo clic sulla proprietà DropDownList Items nel Finestra Proprietà (che visualizzerà il ListItem Editor Collection). Tuttavia, assicurarsi di aggiungere per NULLListItem questa esercitazione tramite la sintassi dichiarativa. Se si usa la ListItem Editor Collection, 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, il valore mancante fa sì che DropDownList usi il valore della Text proprietà al suo posto. Ciò significa che se NULLListItem questa opzione è selezionata, il valore "(None)" verrà tentato di essere assegnato a CategoryID, che genererà un'eccezione. Impostando Value=""in modo esplicito , verrà assegnato un NULL valore a CategoryID quando viene selezionato .NULLListItem

Ripetere questi passaggi per l'elenco a discesa Suppliers.

Con questo ulteriore ListItem, l'interfaccia di modifica può ora assegnare NULL valori ai campi e SupplierID di CategoryID un prodotto, come illustrato nella figura 12.

Scegliere (Nessuno) per assegnare un valore NULL per la categoria o il fornitore di un prodotto

Figura 12: Scegliere (Nessuno) per assegnare un valore per la categoria o il fornitore di un prodotto (fare clic per visualizzare l'immagineNULL a dimensione intera)

Passaggio 4: Uso dei pulsanti di opzione per lo stato sospeso

Attualmente il campo dati dei Discontinued prodotti viene espresso utilizzando un campo CheckBox, che esegue il rendering di una casella di controllo disabilitata per le righe di sola lettura e una casella di controllo abilitata per la riga da modificare. Anche se questa interfaccia utente è spesso adatta, è possibile personalizzarla se necessario usando un campo TemplateField. Per questa esercitazione, si modificherà CheckBoxField in un campo Modello che usa un controllo RadioButtonList con due opzioni "Active" e "Discontinued" da cui l'utente può specificare il valore del Discontinued prodotto.

Per iniziare, convertire checkBoxField Discontinued in un oggetto TemplateField, che creerà un oggetto TemplateField con un ItemTemplate oggetto e EditItemTemplate. Entrambi i modelli includono un controllo CheckBox con la relativa Checked proprietà associata al Discontinued campo dati, l'unica differenza tra i due è che la ItemTemplateproprietà checkBox dell'oggetto Enabled è impostata su false.

Sostituire CheckBox in e ItemTemplateEditItemTemplate con un controllo RadioButtonList, impostando entrambe le proprietà di ID RadioButtonLists su DiscontinuedChoice. Indicare quindi che RadioButtonLists deve contenere ognuno due pulsanti di opzione, uno con etichetta "Active" con un valore "False" e uno con etichetta "Discontinued" con il valore "True". A tale scopo, è possibile immettere gli <asp:ListItem> elementi in direttamente tramite la sintassi dichiarativa oppure usare il ListItem Editor Collection dal Designer. La figura 13 mostra la ListItem Editor Raccolta dopo che sono state specificate le due opzioni del pulsante di opzione.

Add

Figura 13: Aggiungere le opzioni "Active" e "Discontinued" a RadioButtonList (fare clic per visualizzare l'immagine a dimensione intera)

Poiché RadioButtonList in ItemTemplate non deve essere modificabile, impostarne la Enabled proprietà su false, lasciando la Enabled proprietà su true (impostazione predefinita) per RadioButtonList in EditItemTemplate. In questo modo i pulsanti di opzione nella riga non modificata saranno di sola lettura, ma consentiranno all'utente di modificare i valori radiobutton per la riga modificata.

È comunque necessario assegnare le proprietà dei SelectedValue controlli RadioButtonList in modo che il pulsante di opzione appropriato sia selezionato in base al campo dati del Discontinued prodotto. Come per gli DropDownList esaminati in precedenza in questa esercitazione, questa sintassi di associazione dati può essere aggiunta direttamente nel markup dichiarativo o tramite il collegamento Edit DataBindings negli smart tag RadioButtonLists.

Dopo aver aggiunto i due RadioButtonLists e averli configurati, il Discontinued markup dichiarativo di TemplateField avrà un aspetto simile al seguente:

<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
    <ItemTemplate>
        <asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
          Enabled="False" SelectedValue='<%# Bind("Discontinued") %>'>
            <asp:ListItem Value="False">Active</asp:ListItem>
            <asp:ListItem Value="True">Discontinued</asp:ListItem>
        </asp:RadioButtonList>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
            SelectedValue='<%# Bind("Discontinued") %>'>
            <asp:ListItem Value="False">Active</asp:ListItem>
            <asp:ListItem Value="True">Discontinued</asp:ListItem>
        </asp:RadioButtonList>
    </EditItemTemplate>
</asp:TemplateField>

Con queste modifiche, la Discontinued colonna è stata trasformata da un elenco di caselle di controllo a un elenco di coppie di pulsanti di opzione (vedere la figura 14). Quando si modifica un prodotto, viene selezionato il pulsante di opzione appropriato e lo stato di interruzione del prodotto può essere aggiornato selezionando l'altro pulsante di opzione e facendo clic su Aggiorna.

Le caselle di controllo sospese sono state sostituite da coppie di pulsanti di opzione

Figura 14: Le caselle di controllo sospese sono state sostituite da coppie di pulsanti di opzione (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Poiché la Discontinued colonna nel Products database non può avere NULL valori, non è necessario preoccuparsi dell'acquisizione delle NULL informazioni nell'interfaccia. Se, tuttavia, Discontinued la colonna potrebbe contenere NULL valori che si vuole aggiungere un terzo pulsante di opzione all'elenco con il relativo Value set su una stringa vuota (Value=""), proprio come con la categoria e i fornitori DropDownList.

Riepilogo

Mentre BoundField e CheckBoxField eseguono automaticamente il rendering di interfacce di sola lettura, modifica e inserimento, non hanno la possibilità di personalizzare. Spesso, tuttavia, è necessario personalizzare l'interfaccia di modifica o inserimento, ad esempio aggiungendo controlli di convalida (come illustrato nell'esercitazione precedente) o personalizzando l'interfaccia utente della raccolta dati (come illustrato in questa esercitazione). La personalizzazione dell'interfaccia con un oggetto TemplateField può essere riassunta nei passaggi seguenti:

  1. Aggiungere un oggetto TemplateField o convertire un campo BoundField o CheckBoxField esistente in un campo Template
  2. Aumentare l'interfaccia in base alle esigenze
  3. Associare i campi dati appropriati ai controlli Web appena aggiunti usando il databinding bidirezionale

Oltre a usare i controlli Web predefiniti ASP.NET, è anche possibile personalizzare i modelli di un oggetto TemplateField con controlli server personalizzati e compilati e controlli utente.

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.