Inserimento di un nuovo record dal piè di pagina di GridView (VB)

di Scott Mitchell

Scarica il PDF

Anche se il controllo GridView non fornisce supporto predefinito per l'inserimento di un nuovo record di dati, questa esercitazione illustra come aumentare GridView per includere un'interfaccia di inserimento.

Introduzione

Come illustrato nell'esercitazione Panoramica dell'inserimento, dell'aggiornamento e dell'eliminazione dei dati , i controlli Web GridView, DetailsView e FormView includono funzionalità di modifica dei dati predefinite. Quando viene usato con controlli origine dati dichiarativi, questi tre controlli Web possono essere rapidamente e facilmente configurati per modificare i dati e in scenari senza dover scrivere una singola riga di codice. Sfortunatamente, solo i controlli DetailsView e FormView forniscono funzionalità predefinite di inserimento, modifica ed eliminazione. GridView offre solo la modifica e l'eliminazione del supporto. Tuttavia, con un piccolo grasso gomito, è possibile aumentare GridView per includere un'interfaccia di inserimento.

Nell'aggiunta delle funzionalità di inserimento a GridView, si è responsabili della scelta della modalità di aggiunta di nuovi record, della creazione dell'interfaccia di inserimento e della scrittura del codice per inserire il nuovo record. In questa esercitazione verrà esaminata l'aggiunta dell'interfaccia di inserimento alla riga piè di pagina di GridView (vedere la figura 1). La cella piè di pagina per ogni colonna include l'elemento dell'interfaccia utente della raccolta dati appropriato (un oggetto TextBox per il nome del prodotto, un elenco a discesa per il fornitore e così via). È necessaria anche una colonna per un pulsante Aggiungi che, quando viene fatto clic, causerà un postback e inserisce un nuovo record Products nella tabella usando i valori forniti nella riga del piè di pagina.

La riga piè di pagina fornisce un'interfaccia per l'aggiunta di nuovi prodotti

Figura 1: La riga piè di pagina fornisce un'interfaccia per l'aggiunta di nuovi prodotti (fare clic per visualizzare l'immagine full-size)

Passaggio 1: Visualizzazione delle informazioni sul prodotto in un controllo GridView

Prima di preoccuparsi della creazione dell'interfaccia di inserimento nel piè di pagina di GridView, è prima necessario concentrarsi sull'aggiunta di Un controllo GridView alla pagina che elenca i prodotti nel database. Iniziare aprendo la InsertThroughFooter.aspx pagina nella EnhancedGridView cartella e trascinando gridView dalla casella degli strumenti nella Designer, impostando la proprietà ProductsGridView su ID . Usare quindi lo smart tag di GridView per associarlo a un nuovo oggetto ObjectDataSource denominato ProductsDataSource.

Creare un nuovo oggettoDataSource denominato ProductsDataSource

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

Configurare ObjectDataSource per usare il ProductsBLL metodo della GetProducts() classe per recuperare le informazioni sul prodotto. Per questa esercitazione, consente di concentrarsi rigorosamente sull'aggiunta di funzionalità di inserimento e non preoccuparsi della modifica e dell'eliminazione. Assicurarsi pertanto che l'elenco a discesa nella scheda INSERT sia impostato su AddProduct() e che gli elenchi a discesa nelle schede UPDATE e DELETE siano impostati su (Nessuno).

Eseguire il mapping del metodo AddProduct al metodo Insert() di ObjectDataSource

Figura 3: Eseguire il mapping del metodo al metodo ObjectDataSource (Insert()Fare clic per visualizzare l'immagineAddProduct full-size)

Impostare le schede UPDATE e DELETE Drop-Down Elenchi su (Nessuna)

Figura 4: Impostare le schede UPDATE ed DELETE Drop-Down Elenchi su (Nessuno) (Fare clic per visualizzare l'immagine a dimensioni complete)

Dopo aver completato la procedura guidata Configura origine dati di ObjectDataSource, Visual Studio aggiungerà automaticamente campi a GridView per ognuno dei campi dati corrispondenti. Per il momento, lasciare tutti i campi aggiunti da Visual Studio. Più avanti in questa esercitazione verrà restituito e rimosso alcuni dei campi i cui valori non devono essere specificati quando si aggiunge un nuovo record.

Poiché nel database sono presenti quasi 80 prodotti, un utente dovrà scorrere fino alla fine della pagina Web per aggiungere un nuovo record. Di conseguenza, consente di abilitare il paging per rendere più visibile e accessibile l'interfaccia di inserimento. Per attivare il paging, selezionare semplicemente la casella di controllo Abilita paging dalla smart tag di GridView.

A questo punto, il markup dichiarativo gridView e ObjectDataSource deve essere simile al seguente:

<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
    AllowPaging="True" EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
            InsertVisible="False" ReadOnly="True" 
            SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
            SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" 
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" 
            SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit" 
            SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
            SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" 
            SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder" 
            SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel" 
            SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" 
            SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" 
            ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="SupplierName" 
            ReadOnly="True" SortExpression="SupplierName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
    InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}" 
    SelectMethod="GetProducts" TypeName="ProductsBLL">
    <InsertParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
    </InsertParameters>
</asp:ObjectDataSource>

Tutti i campi dei dati del prodotto vengono visualizzati in un controllo GridView paginato

Figura 5: tutti i campi dati del prodotto vengono visualizzati in un controllo GridView paginato (fare clic per visualizzare l'immagine full-size)

Oltre alle righe di intestazione e dati, GridView include una riga piè di pagina. Le righe di intestazione e piè di pagina vengono visualizzate a seconda dei valori delle proprietà e ShowFooter di ShowHeader GridView. Per visualizzare la riga del piè di pagina, è sufficiente impostare la ShowFooter proprietà su True. Come illustrato nella figura 6, impostare la ShowFooter proprietà per True aggiungere una riga piè di pagina alla griglia.

Per visualizzare la riga piè di pagina, impostare ShowFooter su True

Figura 6: Per visualizzare la riga piè di pagina, impostare ShowFooter su True (fare clic per visualizzare l'immagine a dimensioni complete)

Si noti che la riga del piè di pagina ha un colore di sfondo rosso scuro. Questo è dovuto al tema DataWebControls creato e applicato a tutte le pagine nell'esercitazione Visualizzazione dati con ObjectDataSource . In particolare, il GridView.skin file configura la FooterStyle proprietà in modo che usi la FooterStyle classe CSS. La FooterStyle classe è definita nel Styles.css modo seguente:

.FooterStyle
{
    background-color: #a33;
    color: White;
    text-align: right;
}

Nota

È stata illustrata l'uso della riga piè di pagina di GridView nelle esercitazioni precedenti. Se necessario, fare riferimento all'esercitazione Visualizza informazioni di riepilogo nell'esercitazione Piè di pagina di GridView per un aggiornamento.

Dopo aver impostato la proprietà su True, richiedere un momento per visualizzare l'output ShowFooter in un browser. Attualmente la riga del piè di pagina non contiene alcun testo o controlli Web. Nel passaggio 3 verrà modificato il piè di pagina per ogni campo GridView in modo che includa l'interfaccia di inserimento appropriata.

La riga piè di pagina vuota viene visualizzata sopra i controlli dell'interfaccia di paging

Figura 7: La riga piè di pagina vuota viene visualizzata sopra i controlli dell'interfaccia di paging (fare clic per visualizzare l'immagine full-size)

Nell'esercitazione Uso di TemplateFields nell'esercitazione Controllo GridView è stato illustrato come personalizzare notevolmente la visualizzazione di una determinata colonna GridView usando TemplateFields (anziché BoundFields o CheckBoxFields); in Personalizzazione dell'interfaccia di modifica dei dati esaminata tramite TemplateFields per personalizzare l'interfaccia di modifica in un oggetto GridView. Si ricordi che un ModelloField è costituito da un numero di modelli che definisce la combinazione di markup, controlli Web e sintassi di associazione dati utilizzata per determinati tipi di righe. Ad ItemTemplateesempio, specifica il modello usato per le righe di sola lettura, mentre il EditItemTemplate modello definisce il modello per la riga modificabile.

Insieme a ItemTemplate e EditItemTemplate, templateField include anche un FooterTemplate oggetto che specifica il contenuto per la riga piè di pagina. È pertanto possibile aggiungere i controlli Web necessari per ogni interfaccia di inserimento di campi nell'oggetto FooterTemplate. Per iniziare, convertire tutti i campi in GridView in TemplateFields. Questa operazione può essere eseguita facendo clic sul collegamento Modifica colonne nello smart tag gridView, selezionando ogni campo nell'angolo inferiore sinistro e facendo clic sul collegamento Converti questo campo in un campo TemplateField.

Convertire ogni campo in un modelloField

Figura 8: Convertire ogni campo in un modelloField

Facendo clic sul campo Convert this in a TemplateField viene trasformato il tipo di campo corrente in un modello equivalente. Ad esempio, ogni oggetto BoundField viene sostituito da un Oggetto TemplateField con un ItemTemplate oggetto che contiene un'etichetta che visualizza il campo dati corrispondente e un EditItemTemplate oggetto che visualizza il campo dati in una casella di testo. L'oggetto ProductName BoundField è stato convertito nel markup TemplateField seguente:

<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName">
    <EditItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server" 
            Text='<%# Bind("ProductName") %>'></asp:TextBox>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label2" runat="server" 
            Text='<%# Bind("ProductName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Analogamente, CheckBoxField Discontinued è stato convertito in un TemplateField il cui ItemTemplate e EditItemTemplate contiene un controllo Web CheckBox (con checkBox ItemTemplate disabilitato). L'oggetto BoundField di sola lettura ProductID è stato convertito in un oggetto TemplateField con un controllo Label sia in ItemTemplateEditItemTemplate. In breve, la conversione di un campo GridView esistente in un ModelloField è un modo rapido e semplice per passare al ModelloField più personalizzabile senza perdere alcuna funzionalità del campo esistente.

Poiché GridView si sta lavorando a non supporta la modifica, è possibile rimuovere l'oggetto da ogni ModelloField, lasciando solo l'oggetto EditItemTemplateItemTemplate. Dopo aver eseguito questa operazione, il markup dichiarativo di GridView dovrebbe essere simile al seguente:

<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
    AllowPaging="True" EnableViewState="False" ShowFooter="True">
    <Columns>
        <asp:TemplateField HeaderText="ProductID" InsertVisible="False" 
            SortExpression="ProductID">
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" 
                    Text='<%# Bind("ProductID") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="ProductName" SortExpression="ProductName">
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" 
                    Text='<%# Bind("ProductName") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="SupplierID" SortExpression="SupplierID">
            <ItemTemplate>
                <asp:Label ID="Label3" runat="server" 
                    Text='<%# Bind("SupplierID") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="CategoryID" SortExpression="CategoryID">
            <ItemTemplate>
                <asp:Label ID="Label4" runat="server" 
                    Text='<%# Bind("CategoryID") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="QuantityPerUnit" 
            SortExpression="QuantityPerUnit">
            <ItemTemplate>
                <asp:Label ID="Label5" runat="server" 
                    Text='<%# Bind("QuantityPerUnit") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="UnitPrice" SortExpression="UnitPrice">
            <ItemTemplate>
                <asp:Label ID="Label6" runat="server" 
                    Text='<%# Bind("UnitPrice") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="UnitsInStock" 
            SortExpression="UnitsInStock">
            <ItemTemplate>
                <asp:Label ID="Label7" runat="server" 
                    Text='<%# Bind("UnitsInStock") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="UnitsOnOrder" 
            SortExpression="UnitsOnOrder">
            <ItemTemplate>
                <asp:Label ID="Label8" runat="server" 
                    Text='<%# Bind("UnitsOnOrder") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="ReorderLevel" 
            SortExpression="ReorderLevel">
            <ItemTemplate>
                <asp:Label ID="Label9" runat="server" 
                    Text='<%# Bind("ReorderLevel") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Discontinued" 
            SortExpression="Discontinued">
            <ItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server" 
                    Checked='<%# Bind("Discontinued") %>' Enabled="false" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="CategoryName" 
            SortExpression="CategoryName">
            <ItemTemplate>
                <asp:Label ID="Label10" runat="server" 
                    Text='<%# Bind("CategoryName") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="SupplierName" 
            SortExpression="SupplierName">
            <ItemTemplate>
                <asp:Label ID="Label11" runat="server" 
                    Text='<%# Bind("SupplierName") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Ora che ogni campo GridView è stato convertito in un ModelloField, è possibile immettere l'interfaccia di inserimento appropriata in ogni campo s FooterTemplate. Alcuni dei campi non avranno un'interfaccia di inserimento (ProductIDad esempio); altri variano nei controlli Web usati per raccogliere le informazioni del nuovo prodotto.

Per creare l'interfaccia di modifica, scegliere il collegamento Modifica modelli dallo smart tag GridView. Nell'elenco a discesa selezionare quindi il campo FooterTemplate appropriato e trascinare il controllo appropriato dalla casella degli strumenti nella Designer.

Aggiungere l'interfaccia di inserimento appropriata a ogni piè di pagina del campo

Figura 9: Aggiungere l'interfaccia di inserimento appropriata a ogni campo FooterTemplate (fare clic per visualizzare l'immagine full-size)

L'elenco puntato seguente enumera i campi GridView, specificando l'interfaccia di inserimento da aggiungere:

  • ProductID Nessuno.
  • ProductName aggiungere un controllo TextBox e impostarne l'oggetto ID su NewProductName. Aggiungere un controllo RequiredFieldValidator e assicurarsi che l'utente immetta un valore per il nome del nuovo prodotto.
  • SupplierID Nessuno.
  • CategoryID Nessuno.
  • QuantityPerUnit aggiungere un controllo TextBox, impostandone su IDNewQuantityPerUnit.
  • UnitPrice aggiungere un oggetto TextBox denominato NewUnitPrice e un CompareValidator che assicura che il valore immesso sia un valore di valuta maggiore o uguale a zero.
  • UnitsInStock usare TextBox il cui ID valore è impostato su NewUnitsInStock. Includere un CompareValidator che garantisce che il valore immesso sia un valore intero maggiore o uguale a zero.
  • UnitsOnOrder usare TextBox il cui ID valore è impostato su NewUnitsOnOrder. Includere un CompareValidator che garantisce che il valore immesso sia un valore intero maggiore o uguale a zero.
  • ReorderLevel usare TextBox il cui ID valore è impostato su NewReorderLevel. Includere un CompareValidator che garantisce che il valore immesso sia un valore intero maggiore o uguale a zero.
  • Discontinued aggiungere un controllo CheckBox, impostandone su IDNewDiscontinued.
  • CategoryName aggiungere un elenco DropDownList e impostarne l'oggetto ID su NewCategoryID. Associarlo a un nuovo OggettoDataSource denominato CategoriesDataSource e configurarlo per usare il CategoriesBLL metodo della GetCategories() classe. Visualizzare il campo dati di DropDownList ListItem usando il CategoryNameCategoryID campo dati come valori.
  • SupplierName aggiungere un elenco DropDownList e impostarne l'oggetto ID su NewSupplierID. Associarlo a un nuovo OggettoDataSource denominato SuppliersDataSource e configurarlo per usare il SuppliersBLL metodo della GetSuppliers() classe. Visualizzare il campo dati di DropDownList ListItem usando il CompanyNameSupplierID campo dati come valori.

Per ognuno dei controlli di convalida deselezionare la ForeColor proprietà in modo che il colore di primo piano della FooterStyle classe CSS venga usato al posto del rosso predefinito. Usare anche la ErrorMessage proprietà per una descrizione dettagliata, ma impostare la Text proprietà su un asterisco. Per evitare che il testo del controllo di convalida causa l'inserimento dell'interfaccia a due righe, impostare la FooterStyle proprietà s Wrap su false per ognuna delle FooterTemplate quali usa un controllo di convalida. Infine, aggiungere un controllo ValidationSummary sotto GridView e impostarne la ShowMessageBox proprietà su True e la relativa ShowSummary proprietà su False.

Quando si aggiunge un nuovo prodotto, è necessario fornire e CategoryIDSupplierID. Queste informazioni vengono acquisite tramite DropDownList nelle celle piè di pagina per i CategoryName campi e SupplierName . Ho scelto di usare questi campi anziché i campi e SupplierID TemplateFields perché nelle righe di dati della griglia l'utente è probabilmente più interessato a CategoryID visualizzare le categorie e i nomi dei fornitori anziché i relativi valori ID. Poiché i CategoryID valori e SupplierID vengono ora acquisiti nelle CategoryName interfacce di inserimento dei campi e, è possibile rimuovere i CategoryID campi e SupplierNameSupplierID i campi da GridView.

Analogamente, l'oggetto ProductID non viene usato quando si aggiunge un nuovo prodotto, pertanto ProductID è possibile rimuovere anche TemplateField. Tuttavia, lasciare il ProductID campo nella griglia. Oltre ai controlli TextBoxes, DropDownLists, CheckBox e convalida che costituiscono l'interfaccia di inserimento, sarà necessario anche un pulsante Aggiungi che, quando fatto clic, esegue la logica per aggiungere il nuovo prodotto al database. Nel passaggio 4 verrà incluso un pulsante Aggiungi nell'interfaccia di inserimento in ProductID TemplateField s FooterTemplate.

È possibile migliorare l'aspetto dei vari campi GridView. Ad esempio, è possibile formattare i valori come valuta, allineare a destra i UnitPriceUnitsInStockcampi , UnitsOnOrdere ReorderLevel aggiornare i HeaderText valori per TemplateFields.

Dopo aver creato le interfacce di inserimento nelle FooterTemplate interfacce, rimuovendo SupplierID, e CategoryID TemplateFields e migliorando l'estetica della griglia attraverso la formattazione e l'allineamento di TemplateFields, il markup dichiarativo di GridView dovrebbe essere simile al seguente:

<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
    AllowPaging="True" EnableViewState="False" ShowFooter="True">
    <Columns>
        <asp:TemplateField HeaderText="ProductID" InsertVisible="False" 
            SortExpression="ProductID">
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" 
                    Text='<%# Bind("ProductID") %>'></asp:Label>
            </ItemTemplate>
            <ItemStyle HorizontalAlign="Center" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Product" SortExpression="ProductName">
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" 
                    Text='<%# Bind("ProductName") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="NewProductName" runat="server"></asp:TextBox>
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1" 
                    runat="server" ControlToValidate="NewProductName"
                    Display="Dynamic"  ForeColor="
                    ErrorMessage="You must enter a name for the new product.">
                    * </asp:RequiredFieldValidator>
            </FooterTemplate>
            <FooterStyle Wrap="False" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
            <ItemTemplate>
                <asp:Label ID="Label10" runat="server" 
                    Text='<%# Bind("CategoryName") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:DropDownList ID="NewCategoryID" 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>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Supplier" SortExpression="SupplierName">
            <ItemTemplate>
                <asp:Label ID="Label11" runat="server" 
                    Text='<%# Bind("SupplierName") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:DropDownList ID="NewSupplierID" runat="server" 
                    DataSourceID="SuppliersDataSource"
                    DataTextField="CompanyName" DataValueField="SupplierID">
                </asp:DropDownList><asp:ObjectDataSource ID="SuppliersDataSource" 
                    runat="server" OldValuesParameterFormatString="original_{0}" 
                    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
                </asp:ObjectDataSource>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Qty/Unit" SortExpression="QuantityPerUnit">
            <ItemTemplate>
                <asp:Label ID="Label5" runat="server" 
                    Text='<%# Bind("QuantityPerUnit") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="NewQuantityPerUnit" runat="server"></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
            <ItemTemplate>
                <asp:Label ID="Label6" runat="server" 
                    Text='<%# Bind("UnitPrice", "{0:c}") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                $<asp:TextBox ID="NewUnitPrice" runat="server" Columns="8" />
                <asp:CompareValidator ID="CompareValidator1" runat="server" 
                    ControlToValidate="NewUnitPrice"
                    ErrorMessage="You must enter a valid currency value greater than 
                        or equal to 0.00. Do not include the currency symbol."
                    ForeColor="" Operator="GreaterThanEqual" Type="Currency" 
                    ValueToCompare="0" Display="Dynamic">
                    * </asp:CompareValidator>
            </FooterTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <FooterStyle Wrap="False" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Units In Stock" 
            SortExpression="Units In Stock">
            <ItemTemplate>
                <asp:Label ID="Label7" runat="server" 
                    Text='<%# Bind("UnitsInStock") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="NewUnitsInStock" runat="server" Columns="5" />
                <asp:CompareValidator ID="CompareValidator2" runat="server" 
                    ControlToValidate="NewUnitsInStock" Display="Dynamic" 
                    ErrorMessage="You must enter a valid numeric value for units 
                        in stock that's greater than or equal to zero."
                    ForeColor="" Operator="GreaterThanEqual" Type="Integer" 
                        ValueToCompare="0">*</asp:CompareValidator>
            </FooterTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <FooterStyle Wrap="False" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Units On Order" SortExpression="UnitsOnOrder">
            <ItemTemplate>
                <asp:Label ID="Label8" runat="server" 
                    Text='<%# Bind("UnitsOnOrder") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="NewUnitsOnOrder" runat="server" Columns="5" />
                <asp:CompareValidator ID="CompareValidator3" runat="server" 
                    ControlToValidate="NewUnitsOnOrder" Display="Dynamic" 
                    ErrorMessage="You must enter a valid numeric value for units on 
                        order that's greater than or equal to zero."
                    ForeColor="" Operator="GreaterThanEqual" Type="Integer" 
                    ValueToCompare="0">*</asp:CompareValidator>
            </FooterTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <FooterStyle Wrap="False" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Reorder Level" SortExpression="ReorderLevel">
            <ItemTemplate>
                <asp:Label ID="Label9" runat="server" 
                    Text='<%# Bind("ReorderLevel") %>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="NewReorderLevel" runat="server" Columns="5" />
                <asp:CompareValidator ID="CompareValidator4" runat="server" 
                    ControlToValidate="NewReorderLevel" Display="Dynamic" 
                    ErrorMessage="You must enter a valid numeric value for reorder 
                        level that's greater than or equal to zero."
                    ForeColor="" Operator="GreaterThanEqual" Type="Integer" 
                    ValueToCompare="0">*</asp:CompareValidator>
            </FooterTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <FooterStyle Wrap="False" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
            <ItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server" 
                    Checked='<%# Bind("Discontinued") %>' Enabled="false" />
            </ItemTemplate>
            <FooterTemplate>
                <asp:CheckBox ID="NewDiscontinued" runat="server" />
            </FooterTemplate>
            <ItemStyle HorizontalAlign="Center" />
            <FooterStyle HorizontalAlign="Center" />
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Quando viene visualizzato tramite un browser, la riga piè di pagina di GridView ora include l'interfaccia di inserimento completata (vedere la figura 10). A questo punto, l'interfaccia di inserimento non include un mezzo per l'utente per indicare che ha immesso i dati per il nuovo prodotto e vuole inserire un nuovo record nel database. Inoltre, i dati immessi nel piè di pagina verranno convertiti in un nuovo record nel Products database. Nel passaggio 4 verrà illustrato come includere un pulsante Aggiungi all'interfaccia di inserimento e come eseguire il codice nel postback quando viene fatto clic su . Il passaggio 5 illustra come inserire un nuovo record usando i dati dal piè di pagina.

Il piè di pagina GridView fornisce un'interfaccia per l'aggiunta di un nuovo record

Figura 10: Il piè di pagina GridView fornisce un'interfaccia per l'aggiunta di un nuovo record (fare clic per visualizzare un'immagine full-size)

Passaggio 4: Inclusione di un pulsante Aggiungi nell'interfaccia di inserimento

È necessario includere un pulsante Aggiungi da qualche parte nell'interfaccia di inserimento perché l'interfaccia di inserimento della riga piè di pagina attualmente non contiene i mezzi per l'utente per indicare che hanno completato l'immissione delle informazioni del nuovo prodotto. Ciò potrebbe essere inserito in uno dei valori esistenti FooterTemplate oppure è possibile aggiungere una nuova colonna alla griglia per questo scopo. Per questa esercitazione, consente di posizionare il pulsante Aggiungi in ProductID TemplateField s FooterTemplate.

Dal Designer fare clic sul collegamento Modifica modelli nel smart tag GridView e quindi scegliere il ProductID campo dall'elenco FooterTemplate a discesa. Aggiungere un controllo Web Button (o un LinkButton o ImageButton, se si preferisce) al modello, impostandone l'ID su AddProduct, CommandName su Inserisci e la relativa Text proprietà su Aggiungi come illustrato nella figura 11.

Posizionare il pulsante Aggiungi nel modello ProductIDField Piè di pagina

Figura 11: Posizionare il pulsante Aggiungi nel ProductID ModelloField (FooterTemplateFare clic per visualizzare l'immagine a dimensioni complete)

Dopo aver incluso il pulsante Aggiungi, testare la pagina in un browser. Si noti che quando si fa clic sul pulsante Aggiungi con dati non validi nell'interfaccia di inserimento, il postback è corto circuito e il controllo ValidationSummary indica i dati non validi (vedere La figura 12). Con i dati appropriati immessi, facendo clic sul pulsante Aggiungi viene generato un postback. Non viene tuttavia aggiunto alcun record al database. Sarà necessario scrivere un po' di codice per eseguire effettivamente l'inserimento.

Il postback del pulsante Aggiungi è corto circuito se nell'interfaccia di inserimento non sono presenti dati non validi

Figura 12: Il postback del pulsante aggiungi è corto circuito se nell'interfaccia di inserimento sono presenti dati non validi (fare clic per visualizzare l'immagine full-size)

Nota

I controlli di convalida nell'interfaccia di inserimento non sono stati assegnati a un gruppo di convalida. Questa operazione funziona correttamente, purché l'interfaccia di inserimento sia l'unico set di controlli di convalida nella pagina. Se, tuttavia, sono presenti altri controlli di convalida nella pagina (ad esempio i controlli di convalida nell'interfaccia di modifica della griglia), i controlli di convalida nell'interfaccia di inserimento e le proprietà aggiungi ValidationGroup pulsanti devono essere assegnati allo stesso valore in modo da associare questi controlli a un determinato gruppo di convalida. Per altre informazioni sul partizionamento dei controlli di convalida in ASP.NET 2.0, vedere Suddivisione dei controlli di convalida e dei pulsanti in una pagina nei gruppi di convalida.

Passaggio 5: Inserimento di un nuovo record nellaProductstabella

Quando si utilizzano le funzionalità di modifica predefinite di GridView, GridView gestisce automaticamente tutte le operazioni necessarie per eseguire l'aggiornamento. In particolare, quando il pulsante Update viene fatto clic, copia i valori immessi dall'interfaccia di modifica ai parametri dell'insieme ObjectDataSource e avvia l'aggiornamento richiamando il metodo ObjectDataSource s UpdateParametersUpdate() . Poiché GridView non fornisce funzionalità predefinite per l'inserimento, è necessario implementare il codice che chiama il metodo ObjectDataSource e copia i valori dall'interfaccia di inserimento all'insieme ObjectDataSourceInsert().InsertParameters

Questa logica di inserimento deve essere eseguita dopo che è stato fatto clic sul pulsante Aggiungi. Come illustrato nell'esercitazione Aggiunta e risposta ai pulsanti in un'esercitazione gridView , in qualsiasi momento viene fatto clic su Button, LinkButton o ImageButton in un oggetto GridView, viene attivato l'evento GridView sul RowCommand postback. Questo evento genera se il pulsante, linkButton o ImageButton è stato aggiunto in modo esplicito, ad esempio il pulsante Aggiungi nella riga del piè di pagina o se è stato aggiunto automaticamente da GridView( ad esempio LinkButtons nella parte superiore di ogni colonna quando si seleziona Abilita ordinamento oppure i LinkButton nell'interfaccia di paging quando si seleziona Abilita paging).

Pertanto, per rispondere all'utente facendo clic sul pulsante Aggiungi, è necessario creare un gestore eventi per l'evento GridView s RowCommand . Poiché questo evento viene generato ogni volta che viene fatto clic su Button, LinkButton o ImageButton in GridView, è fondamentale procedere solo con la logica di inserimento se la CommandName proprietà passata al gestore eventi esegue il mapping al CommandName valore del pulsante Aggiungi ( Inserisci ). Inoltre, è necessario procedere solo se i controlli di convalida segnalano dati validi. Per supportare questa operazione, creare un gestore eventi per l'evento con il RowCommand codice seguente:

Protected Sub Products_RowCommand(sender As Object, e As GridViewCommandEventArgs) _
    Handles Products.RowCommand
    
    ' Insert data if the CommandName == "Insert" 
    ' and the validation controls indicate valid data...
    If e.CommandName = "Insert" AndAlso Page.IsValid Then
        ' TODO: Insert new record...
    End If
End Sub

Nota

Potrebbe essere necessario chiedersi perché il gestore eventi controlla la Page.IsValid proprietà. Dopo tutto, non verrà eliminato il postback se i dati non validi vengono forniti nell'interfaccia di inserimento? Questo presupposto è corretto finché l'utente non ha disabilitato JavaScript o ha eseguito passaggi per aggirare la logica di convalida lato client. In breve, uno non dovrebbe mai basarsi rigorosamente sulla convalida lato client; È consigliabile eseguire sempre un controllo lato server per la validità prima di usare i dati.

Nel passaggio 1 è stato creato ObjectDataSource ProductsDataSource in modo che Insert() il ProductsBLL relativo metodo venga mappato al metodo della AddProduct classe. Per inserire il nuovo record nella Products tabella, è sufficiente richiamare il metodo ObjectDataSource:Insert()

Protected Sub Products_RowCommand(sender As Object, e As GridViewCommandEventArgs) _
    Handles Products.RowCommand
    
    ' Insert data if the CommandName == "Insert" 
    ' and the validation controls indicate valid data...
    If e.CommandName = "Insert" AndAlso Page.IsValid Then
        ' Insert new record
        ProductsDataSource.Insert()
    End If
End Sub

Ora che il Insert() metodo è stato richiamato, tutto ciò che rimane consiste nel copiare i valori dall'interfaccia di inserimento ai parametri passati al ProductsBLL metodo della classe.AddProduct Come illustrato di nuovo nell'esercitazione Analisi degli eventi associati all'inserimento, all'aggiornamento e all'eliminazione, è possibile eseguire questa operazione tramite l'evento ObjectDataSource.Inserting Inserting Nel caso in cui sia necessario fare riferimento a livello di codice ai controlli dalla Products riga piè di pagina di GridView e assegnare i relativi valori alla e.InputParameters raccolta. Se l'utente omette un valore, ad esempio lasciando ReorderLevel vuoto TextBox, è necessario specificare che il valore inserito nel database deve essere NULL. Poiché il AddProducts metodo accetta tipi nullable per i campi del database nullable, usare semplicemente un tipo nullable e impostarne il valore Nothing nel caso in cui l'input utente venga omesso.

Protected Sub ProductsDataSource_Inserting _
    (sender As Object, e As .ObjectDataSourceMethodEventArgs) _
    Handles ProductsDataSource.Inserting
    
    ' Programmatically reference Web controls in the inserting interface...
    Dim NewProductName As TextBox = _
        Products.FooterRow.FindControl("NewProductName")
    Dim NewCategoryID As DropDownList = _
        Products.FooterRow.FindControl("NewCategoryID")
    Dim NewSupplierID As DropDownList = _
        Products.FooterRow.FindControl("NewSupplierID")
    Dim NewQuantityPerUnit As TextBox = _
        Products.FooterRow.FindControl("NewQuantityPerUnit")
    Dim NewUnitPrice As TextBox = _
        Products.FooterRow.FindControl("NewUnitPrice")
    Dim NewUnitsInStock As TextBox = _
        Products.FooterRow.FindControl("NewUnitsInStock")
    Dim NewUnitsOnOrder As TextBox = _
        Products.FooterRow.FindControl("NewUnitsOnOrder")
    Dim NewReorderLevel As TextBox = _
        Products.FooterRow.FindControl("NewReorderLevel")
    Dim NewDiscontinued As CheckBox = _
        Products.FooterRow.FindControl("NewDiscontinued")
    ' Set the ObjectDataSource's InsertParameters values...
    e.InputParameters("productName") = NewProductName.Text
    e.InputParameters("supplierID") = _
        Convert.ToInt32(NewSupplierID.SelectedValue)
    e.InputParameters("categoryID") = _
        Convert.ToInt32(NewCategoryID.SelectedValue)
    Dim quantityPerUnit As String = Nothing
    If Not String.IsNullOrEmpty(NewQuantityPerUnit.Text) Then
        quantityPerUnit = NewQuantityPerUnit.Text
    End If
    e.InputParameters("quantityPerUnit") = quantityPerUnit
    Dim unitPrice As Nullable(Of Decimal) = Nothing
    If Not String.IsNullOrEmpty(NewUnitPrice.Text) Then
        unitPrice = Convert.ToDecimal(NewUnitPrice.Text)
    End If
    e.InputParameters("unitPrice") = unitPrice
    Dim unitsInStock As Nullable(Of Short) = Nothing
    If Not String.IsNullOrEmpty(NewUnitsInStock.Text) Then
        unitsInStock = Convert.ToInt16(NewUnitsInStock.Text)
    End If
    e.InputParameters("unitsInStock") = unitsInStock
    Dim unitsOnOrder As Nullable(Of Short) = Nothing
    If Not String.IsNullOrEmpty(NewUnitsOnOrder.Text) Then
        unitsOnOrder = Convert.ToInt16(NewUnitsOnOrder.Text)
    End If
    e.InputParameters("unitsOnOrder") = unitsOnOrder
    Dim reorderLevel As Nullable(Of Short) = Nothing
    If Not String.IsNullOrEmpty(NewReorderLevel.Text) Then
        reorderLevel = Convert.ToInt16(NewReorderLevel.Text)
    End If
    e.InputParameters("reorderLevel") = reorderLevel
    e.InputParameters("discontinued") = NewDiscontinued.Checked
End Sub

Dopo il completamento del Inserting gestore eventi, è possibile aggiungere nuovi record alla tabella di database tramite la Products riga piè di pagina di GridView. Vai avanti e prova ad aggiungere diversi nuovi prodotti.

Miglioramento e personalizzazione dell'operazione di aggiunta

Attualmente, facendo clic sul pulsante Aggiungi viene aggiunto un nuovo record alla tabella di database, ma non viene fornito alcun tipo di feedback visivo aggiunto. Idealmente, una casella di avviso Sul Web etichetta o lato client informa l'utente che l'inserimento è stato completato con esito positivo. Lascio questo come esercizio per il lettore.

GridView usato in questa esercitazione non applica alcun ordinamento ai prodotti elencati, né consente all'utente finale di ordinare i dati. Di conseguenza, i record vengono ordinati come si trovano nel database in base al campo chiave primaria. Poiché ogni nuovo record ha un valore maggiore dell'ultimo, ogni volta che viene aggiunto un ProductID nuovo prodotto alla fine della griglia. Pertanto, è possibile inviare automaticamente l'utente all'ultima pagina di GridView dopo aver aggiunto un nuovo record. Questa operazione può essere eseguita aggiungendo la riga di codice seguente dopo la chiamata al ProductsDataSource.Insert()RowCommand gestore eventi per indicare che l'utente deve essere inviato all'ultima pagina dopo l'associazione dei dati a GridView:

' Indicate that the user needs to be sent to the last page
SendUserToLastPage = True

SendUserToLastPage è una variabile booleana a livello di pagina assegnata inizialmente a un valore di False. Nel gestore eventi di GridView, DataBound se SendUserToLastPage è false, la PageIndex proprietà viene aggiornata per inviare l'utente all'ultima pagina.

Protected Sub Products_DataBound(sender As Object, e As EventArgs) _
    Handles Products.DataBound
    
    ' Send user to last page of data, if needed
    If SendUserToLastPage Then
        Products.PageIndex = Products.PageCount - 1
    End If
End Sub

Il motivo per cui la PageIndex proprietà è impostata nel DataBound gestore eventi (anziché nel RowCommand gestore eventi) è perché quando il RowCommand gestore eventi viene attivato non è ancora stato aggiunto al nuovo record alla Products tabella di database. Pertanto, nel RowCommand gestore eventi l'ultimo indice di pagina (PageCount - 1) rappresenta l'ultimo indice di pagina prima dell'aggiunta del nuovo prodotto. Per la maggior parte dei prodotti aggiunti, l'indice dell'ultima pagina è lo stesso dopo l'aggiunta del nuovo prodotto. Tuttavia, quando il prodotto aggiunto restituisce un nuovo indice dell'ultima pagina, se si aggiorna in modo errato l'oggetto PageIndex nel RowCommand gestore eventi, verrà eseguito il passaggio al secondo all'ultima pagina (l'indice dell'ultima pagina prima di aggiungere il nuovo prodotto) anziché al nuovo indice dell'ultima pagina. Poiché il DataBound gestore eventi viene generato dopo l'aggiunta del nuovo prodotto e il rebound dei dati nella griglia, impostando la proprietà che sappiamo di ottenere l'indice PageIndex dell'ultima pagina corretto.

Infine, GridView usato in questa esercitazione è abbastanza ampio a causa del numero di campi che devono essere raccolti per aggiungere un nuovo prodotto. A causa di questa larghezza, potrebbe essere preferibile un layout verticale di DetailsView. La larghezza complessiva di GridView potrebbe essere ridotta raccogliendo meno input. Forse non è necessario raccogliere i UnitsOnOrdercampi , UnitsInStocke ReorderLevel quando si aggiunge un nuovo prodotto, in questo caso questi campi potrebbero essere rimossi da GridView.

Per modificare i dati raccolti, è possibile usare uno dei due approcci seguenti:

  • Continuare a usare il AddProduct metodo che prevede valori per i UnitsOnOrdercampi , UnitsInStocke ReorderLevel . Inserting Nel gestore eventi specificare valori predefiniti predefiniti da usare per questi input rimossi dall'interfaccia di inserimento.
  • Creare un nuovo overload del AddProduct metodo nella ProductsBLL classe che non accetta input per i UnitsOnOrdercampi , UnitsInStocke ReorderLevel . Quindi, nella pagina ASP.NET configurare ObjectDataSource per usare questo nuovo overload.

Entrambe le opzioni funzioneranno ugualmente. Nelle esercitazioni precedenti è stata usata l'ultima opzione, creando più overload per il ProductsBLL metodo della UpdateProduct classe.

Riepilogo

GridView non dispone delle funzionalità di inserimento predefinite trovate in DetailsView e FormView, ma con un po' di sforzo è possibile aggiungere un'interfaccia di inserimento alla riga del piè di pagina. Per visualizzare la riga piè di pagina in gridView, è sufficiente impostare la relativa ShowFooter proprietà su True. Il contenuto della riga del piè di pagina può essere personalizzato per ogni campo convertendo il campo in un ModelloField e aggiungendo l'interfaccia di inserimento all'oggetto FooterTemplate. Come illustrato in questa esercitazione, l'oggetto FooterTemplate può contenere pulsanti, Caselle di testo, DropDownLists, CheckBoxes, controlli origine dati per popolare controlli Web basati su dati (ad esempio DropDownLists) e controlli di convalida. Oltre ai controlli per la raccolta dell'input dell'utente, è necessario aggiungere un pulsante, linkButton o ImageButton.

Quando si fa clic sul pulsante Add, viene richiamato il metodo ObjectDataSource per Insert() avviare il flusso di lavoro di inserimento. ObjectDataSource chiamerà quindi il metodo insert configurato (il ProductsBLL metodo della AddProduct classe, in questa esercitazione). È necessario copiare i valori dall'interfaccia di inserimento di GridView all'insieme ObjectDataSource prima InsertParameters di richiamare il metodo insert. Questa operazione può essere eseguita facendo riferimento a livello di codice ai controlli Web dell'interfaccia di inserimento nel gestore eventi di ObjectDataSource.Inserting

Questa esercitazione completa le tecniche per migliorare l'aspetto di GridView. Il set successivo di esercitazioni esaminerà come usare i dati binari, ad esempio immagini, PDF, Word documenti e così via e i controlli Web dati.

Programmazione felice!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.

Grazie speciali

Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione è stato Bernadette Leigh. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.