Condividi tramite


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

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. Se usato con controlli origine dati dichiarativa, questi tre controlli Web possono essere configurati rapidamente e facilmente 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 supporto per la modifica e l'eliminazione. Tuttavia, con un po ' di grasso gomito, possiamo aumentare GridView per includere un'interfaccia di inserimento.

Nell'aggiunta di funzionalità di inserimento a GridView, è necessario decidere in che modo verranno aggiunti nuovi record, creare l'interfaccia di inserimento e scrivere il codice per inserire il nuovo record. In questa esercitazione verrà esaminata l'aggiunta dell'interfaccia di inserimento alla riga del piè di pagina di GridView (vedere la figura 1). La cella del piè di pagina per ogni colonna include l'elemento dell'interfaccia utente di raccolta dati appropriato (un controllo TextBox per il nome del prodotto, un oggetto DropDownList per il fornitore e così via). È necessaria anche una colonna per un pulsante Aggiungi che, quando si fa clic, causerà un postback e inserisce un nuovo record nella Products tabella usando i valori specificati 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 a dimensione intera)

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

Prima di preoccuparsi di creare l'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. Per iniziare, aprire la InsertThroughFooter.aspx pagina nella EnhancedGridView cartella e trascinare gridView dalla casella degli strumenti nella Designer, impostando la proprietà ProductsgridView su ID . Usare quindi lo smart tag gridView per associarlo a un nuovo ObjectDataSource denominato ProductsDataSource.

Creare un nuovo objectDataSource denominato ProductsDataSource

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

Configurare ObjectDataSource per l'uso del ProductsBLL metodo della GetProducts() classe per recuperare le informazioni sul prodotto. Per questa esercitazione, è possibile concentrarsi esclusivamente 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 AddProduct metodo al metodo ObjectDataSource (Insert()fare clic per visualizzare l'immagine a dimensione intera)

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

Figura 4: Impostare le schede UPDATE e DELETE Drop-Down Elenchi su (Nessuna) (Fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver completato la procedura guidata Configura origine dati di ObjectDataSource, Visual Studio aggiungerà automaticamente i 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 verranno rimossi alcuni 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. Pertanto, consentire il paging per rendere l'interfaccia di inserimento più visibile e accessibile. Per attivare il paging, selezionare semplicemente la casella di controllo Abilita paging dallo smart tag di GridView.

A questo punto, il markup dichiarativo di GridView e ObjectDataSource dovrebbe 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 dati del prodotto vengono visualizzati in un controllo GridView con paging

Figura 5: Tutti i campi dati prodotto vengono visualizzati in un controllo GridView a pagina (fare clic per visualizzare un'immagine a dimensioni intere)

Insieme all'intestazione e alle righe di dati, GridView include una riga del piè di pagina. Le righe di intestazione e piè di pagina vengono visualizzate in base ai 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, l'impostazione della ShowFooter proprietà per true aggiungere una riga del piè di pagina alla griglia.

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

Figura 6: Per visualizzare la riga piè di pagina, impostare su ShowFooterTrue (fare clic per visualizzare l'immagine a dimensione intera)

Si noti che la riga del piè di pagina ha un colore di sfondo rosso scuro. Ciò è dovuto al tema DataWebControls creato e applicato a tutte le pagine nell'esercitazione Visualizzazione dei 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 in Styles.css come segue:

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

Nota

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

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

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

Figura 7: La riga del piè di pagina vuota viene visualizzata sopra i controlli interfaccia di paging (fare clic per visualizzare l'immagine a dimensione intera)

Nell'esercitazione Uso di TemplateFields nell'esercitazione sul 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 usando TemplateFields per personalizzare l'interfaccia di modifica in un controllo GridView. Tenere presente che templateField è costituito da diversi modelli che definiscono la combinazione di markup, controlli Web e sintassi di associazione dati utilizzata per determinati tipi di righe. L'oggetto ItemTemplate, ad esempio, specifica il modello utilizzato per le righe di sola lettura, mentre EditItemTemplate 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 del piè di pagina. È quindi possibile aggiungere i controlli Web necessari per ogni campo che inserisce l'interfaccia FooterTemplatein . Per iniziare, convertire tutti i campi in GridView in TemplateFields. A tale scopo, fare clic sul collegamento Modifica colonne nello smart tag gridView, selezionare ogni campo nell'angolo inferiore sinistro e fare clic sul collegamento Converti questo campo in un campo ModelloCampo.

Convertire ogni campo in un campo modello

Figura 8: Convertire ogni campo in un campo modello

Facendo clic sul campo Converti questo campo in un campo Modello, il tipo di campo corrente viene convertito in un campo modello equivalente. Ad esempio, ogni BoundField viene sostituito da un oggetto TemplateField con un ItemTemplate oggetto contenente un oggetto Label che visualizza il campo dati corrispondente e un oggetto EditItemTemplate che visualizza il campo dati in un controllo TextBox. BoundField ProductName è 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 campo Template il cui ItemTemplate controllo e EditItemTemplate contiene un controllo Web CheckBox (con checkBox ItemTemplate disabilitato). BoundField di sola lettura ProductID è stato convertito in un oggetto TemplateField con un controllo Label in e ItemTemplateEditItemTemplate. In breve, la conversione di un campo GridView esistente in un campo TemplateField è un modo semplice e rapido per passare al campo Modello più personalizzabile senza perdere alcuna funzionalità del campo esistente.

Poiché GridView con cui si sta lavorando non supporta la modifica, è possibile rimuovere l'oggetto EditItemTemplate da ogni oggetto TemplateField, lasciando solo l'oggetto ItemTemplate. 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 campo Modello, è possibile immettere l'interfaccia di inserimento appropriata in ogni campo .FooterTemplate Alcuni campi non avranno un'interfaccia di inserimento (ProductIDad esempio); altre 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 di 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 campoTemplate

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

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

  • ProductID Nessuno.
  • ProductName aggiungere un controllo TextBox e impostarlo ID su NewProductName. Aggiungere anche un controllo RequiredFieldValidator per assicurarsi che l'utente inserisca un valore per il nome del nuovo prodotto.
  • SupplierID Nessuno.
  • CategoryID Nessuno.
  • QuantityPerUnit aggiungere un controllo TextBox, impostandone il ID valore su NewQuantityPerUnit.
  • UnitPrice aggiungere un controllo TextBox denominato NewUnitPrice e un CompareValidator che garantisce che il valore immesso sia un valore di valuta maggiore o uguale a zero.
  • UnitsInStock utilizzare un controllo 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 utilizzare un controllo 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 utilizzare un controllo 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 il ID valore su NewDiscontinued.
  • CategoryName aggiungere un oggetto DropDownList e impostarlo 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 void Products_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // Insert data if the CommandName == "Insert" 
    // and the validation controls indicate valid data...
    if (e.CommandName == "Insert" && Page.IsValid)
    {
        // TODO: Insert new record...
    }
}

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 void Products_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // Insert data if the CommandName == "Insert" 
    // and the validation controls indicate valid data...
    if (e.CommandName == "Insert" && Page.IsValid)
    {
        // Insert new record
        ProductsDataSource.Insert();
    }
}

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 null nel caso in cui l'input utente venga omesso.

protected void ProductsDataSource_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{
    // Programmatically reference Web controls in the inserting interface...
    TextBox NewProductName = 
        (TextBox)Products.FooterRow.FindControl("NewProductName");
    DropDownList NewCategoryID = 
        (DropDownList)Products.FooterRow.FindControl("NewCategoryID");
    DropDownList NewSupplierID = 
        (DropDownList)Products.FooterRow.FindControl("NewSupplierID");
    TextBox NewQuantityPerUnit = 
        (TextBox)Products.FooterRow.FindControl("NewQuantityPerUnit");
    TextBox NewUnitPrice = 
        (TextBox)Products.FooterRow.FindControl("NewUnitPrice");
    TextBox NewUnitsInStock = 
        (TextBox)Products.FooterRow.FindControl("NewUnitsInStock");
    TextBox NewUnitsOnOrder = 
        (TextBox)Products.FooterRow.FindControl("NewUnitsOnOrder");
    TextBox NewReorderLevel = 
        (TextBox)Products.FooterRow.FindControl("NewReorderLevel");
    CheckBox NewDiscontinued = 
        (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);
    
    string quantityPerUnit = null;
    if (!string.IsNullOrEmpty(NewQuantityPerUnit.Text))
        quantityPerUnit = NewQuantityPerUnit.Text;
    e.InputParameters["quantityPerUnit"] = quantityPerUnit;
    decimal? unitPrice = null;
    if (!string.IsNullOrEmpty(NewUnitPrice.Text))
        unitPrice = Convert.ToDecimal(NewUnitPrice.Text);
    e.InputParameters["unitPrice"] = unitPrice;
    short? unitsInStock = null;
    if (!string.IsNullOrEmpty(NewUnitsInStock.Text))
        unitsInStock = Convert.ToInt16(NewUnitsInStock.Text);
    e.InputParameters["unitsInStock"] = unitsInStock;
    short? unitsOnOrder = null;
    if (!string.IsNullOrEmpty(NewUnitsOnOrder.Text))
        unitsOnOrder = Convert.ToInt16(NewUnitsOnOrder.Text);
    e.InputParameters["unitsOnOrder"] = unitsOnOrder;
    short? reorderLevel = null;
    if (!string.IsNullOrEmpty(NewReorderLevel.Text))
        reorderLevel = Convert.ToInt16(NewReorderLevel.Text);
    e.InputParameters["reorderLevel"] = reorderLevel;
    
    e.InputParameters["discontinued"] = NewDiscontinued.Checked;
}

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 void Products_DataBound(object sender, EventArgs e)
{
    // Send user to last page of data, if needed
    if (SendUserToLastPage)
        Products.PageIndex = Products.PageCount - 1;
}

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.