Sdílet prostřednictvím


Vložení nového záznamu ze zápatí prvku GridView (C#)

Scott Mitchell

Stáhnout PDF

Zatímco GridView ovládací prvek neposkytuje integrovanou podporu pro vložení nového záznamu dat, tento kurz ukazuje, jak rozšířit GridView o zahrnutí rozhraní pro vkládání.

Úvod

Jak je popsáno v kurzu Přehled vložení, aktualizace a odstranění dat , ovládací prvky GridView, DetailsView a FormView web obsahují integrované možnosti úprav dat. Při použití s deklarativními ovládacími prvky zdroje dat je možné tyto tři webové ovládací prvky rychle a snadno nakonfigurovat tak, aby upravovaly data – a ve scénářích, aniž by bylo nutné psát jediný řádek kódu. Integrované funkce vkládání, úprav a odstraňování bohužel poskytují pouze ovládací prvky DetailsView a FormView. GridView nabízí pouze podporu úprav a odstraňování. S trochou loketního maziva však můžeme rozšířit GridView o vložení rozhraní.

Při přidávání možností vkládání do GridView jsme zodpovědní za rozhodnutí o tom, jak budou přidány nové záznamy, vytvoření rozhraní pro vkládání a za napsání kódu pro vložení nového záznamu. V tomto kurzu se podíváme na přidání rozhraní pro vkládání do řádku zápatí GridView (viz obrázek 1). Buňka zápatí pro každý sloupec obsahuje příslušný prvek uživatelského rozhraní pro shromažďování dat (textové pole pro název produktu, rozevírací seznam pro dodavatele atd.). Potřebujeme také sloupec pro tlačítko Přidat, které po kliknutí způsobí postback a vloží nový záznam do Products tabulky pomocí hodnot zadaných v řádku zápatí.

Řádek zápatí poskytuje rozhraní pro přidávání nových produktů.

Obrázek 1: Řádek zápatí poskytuje rozhraní pro přidávání nových produktů (kliknutím zobrazíte obrázek v plné velikosti)

Krok 1: Zobrazení informací o produktu v zobrazení GridView

Než se začneme zabývat vytvořením rozhraní pro vkládání v zápatí GridView, pojďme se nejprve zaměřit na přidání GridView na stránku, která obsahuje seznam produktů v databázi. Začněte tím, že InsertThroughFooter.aspx otevřete stránku ve EnhancedGridView složce a přetáhnete GridView z panelu nástrojů do Designer a nastavíte vlastnost GridView s ID na Products. Dále pomocí inteligentní značky GridView s vytvořte vazbu k novému objektu ObjectDataSource s názvem ProductsDataSource.

Vytvoření nového objektuDataSource s názvem ProductsDataSource

Obrázek 2: Vytvoření nového objektuDataSource s názvem ProductsDataSource (kliknutím zobrazíte obrázek v plné velikosti)

Nakonfigurujte ObjectDataSource tak, aby k načtení informací o produktu používal metodu ProductsBLL třídy s GetProducts() . V tomto kurzu se zaměříme výhradně na přidávání možností vkládání a nemusíte se starat o úpravy a odstranění. Proto se ujistěte, že je rozevírací seznam na kartě VLOŽENÍ nastavený na AddProduct() a že rozevírací seznamy na kartách UPDATE a DELETE jsou nastavené na (Žádné) .

Namapujte metodu AddProduct na metodu ObjectDataSource s Insert()

Obrázek 3: Mapování AddProduct metody na metodu ObjectDataSource s Insert() (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte karty UPDATE a DELETE Drop-Down Seznamy na (Žádné).

Obrázek 4: Nastavte karty UPDATE a DELETE Drop-Down Seznamy na (Žádný) (Kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce Konfigurovat zdroj dat ObjectDataSource přidá Visual Studio automaticky pole do objektu GridView pro každé z odpovídajících datových polí. Prozatím ponechte všechna pole přidaná sadou Visual Studio. Později v tomto kurzu se vrátíme a odebereme některá pole, jejichž hodnoty není nutné zadávat při přidávání nového záznamu.

Vzhledem k tomu, že databáze obsahuje téměř 80 produktů, bude se uživatel muset posunout až do dolní části webové stránky, aby mohl přidat nový záznam. Proto povolme stránkování, aby bylo vložené rozhraní viditelnější a přístupnější. Pokud chcete stránkování zapnout, jednoduše zaškrtněte políčko Povolit stránkování u inteligentní značky GridView.

V tomto okamžiku by deklarativní značky GridView a ObjectDataSource měly vypadat podobně jako následující:

<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>

Všechna pole product data jsou zobrazena ve stránkovaném zobrazení GridView

Obrázek 5: Všechna pole s daty produktu se zobrazují v zobrazení Paged GridView (kliknutím zobrazíte obrázek v plné velikosti)

Spolu se záhlavím a řádky dat obsahuje GridView řádek zápatí. Řádky záhlaví a zápatí jsou zobrazeny v závislosti na hodnotách vlastností GridView s ShowHeader a ShowFooter . Pokud chcete zobrazit řádek zápatí, jednoduše nastavte ShowFooter vlastnost na true. Jak znázorňuje obrázek 6, nastavení ShowFooter vlastnosti pro true přidání řádku zápatí do mřížky.

Pokud chcete zobrazit řádek zápatí, nastavte ShowFooter na True.

Obrázek 6: Pokud chcete zobrazit řádek zápatí, nastavit ShowFooter na True (kliknutím zobrazíte obrázek v plné velikosti)

Všimněte si, že řádek zápatí má tmavě červenou barvu pozadí. Důvodem je motiv DataWebControls, který jsme vytvořili a použili na všechny stránky v kurzu Zobrazení dat pomocí ObjectDataSource . Konkrétně GridView.skin soubor konfiguruje FooterStyle vlastnost, která používá FooterStyle třídu CSS. Třída FooterStyle je definována v Styles.css následujícím příkladu:

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

Poznámka

Použití řádku zápatí GridView jsme prozkoumali v předchozích kurzech. V případě potřeby se vraťte k kurzu Zobrazení souhrnných informací v zápatí gridview , kde najdete informace o aktualizaci.

Po nastavení ShowFooter vlastnosti na truechvíli zobrazte výstup v prohlížeči. Řádek zápatí v současné době neobsahuje žádné ovládací prvky pro text ani web. V kroku 3 upravíme zápatí pro každé pole GridView tak, aby obsahovalo příslušné rozhraní pro vkládání.

Prázdný řádek zápatí je zobrazen nad ovládacími prvky stránkovacího rozhraní.

Obrázek 7: Nad ovládacími prvky stránkovacího rozhraní se zobrazuje řádek prázdného zápatí (kliknutím zobrazíte obrázek v plné velikosti)

V kurzu Používání polí šablon v ovládacím prvku GridView jsme viděli, jak výrazně přizpůsobit zobrazení konkrétního sloupce GridView pomocí TemplateFields (na rozdíl od BoundFields nebo CheckBoxFields); v části Přizpůsobení rozhraní pro úpravu dat jsme se podívali na použití TemplateFields k přizpůsobení rozhraní pro úpravy v GridView. Vzpomeňte si, že TemplateField se skládá z řady šablon, které definují kombinaci značek, webových ovládacích prvků a syntaxe vazby dat používané pro určité typy řádků. Například ItemTemplateurčuje šablonu používanou pro řádky jen pro čtení, zatímco EditItemTemplate definuje šablonu pro upravitelný řádek.

Spolu s ItemTemplate a EditItemTemplateobsahuje FooterTemplate TemplateField také objekt, který určuje obsah řádku zápatí. Proto můžeme přidat webové ovládací prvky potřebné pro každé pole s vkládání rozhraní do FooterTemplate. Chcete-li začít, převeďte všechna pole v GridView na TemplateFields. To lze provést kliknutím na odkaz Upravit sloupce v inteligentní značce GridView s, výběrem jednotlivých polí v levém dolním rohu a kliknutím na odkaz Převést toto pole na templatefield.

Převést každé pole na pole šablony

Obrázek 8: Převod každého pole na pole šablony

Kliknutím na převést toto pole na pole TemplateField se aktuální typ pole změní na ekvivalentní TemplateField. Například každý BoundField je nahrazen polem TemplateField za ItemTemplate pole, které obsahuje Popisek, který zobrazuje odpovídající datové pole, a EditItemTemplate pole, které zobrazuje datové pole v textovém poli. BoundField ProductName byl převeden na následující značku TemplateField:

<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>

Stejně tak Discontinued CheckBoxField byl převeden na TemplateField, jehož ItemTemplate a EditItemTemplate obsahuje Ovládací prvek CheckBox Web (se zakázaným ItemTemplate checkBoxem). BoundField jen ProductID pro čtení byla převedena na TemplateField s ovládacím prvku Label v a ItemTemplateEditItemTemplate. Stručně řečeno, převod existujícího pole GridView na TemplateField je rychlý a snadný způsob, jak přepnout na přizpůsobitelné pole TemplateField, aniž by došlo ke ztrátě funkcí existujících polí.

Vzhledem k tomu, že objekt GridView, se kterým pracujeme, nepodporuje úpravy, můžete EditItemTemplate odebrat z každého pole TemplateField a ponechat pouze ItemTemplate. Po provedení tohoto postupu by deklarativní značky GridView měly vypadat takto:

<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>

Nyní, když bylo každé pole GridView převedeno na TemplateField, můžeme do každého pole FooterTemplates zadat příslušné rozhraní pro vkládání . Některá pole nebudou mít například rozhraní pro vkládání,ProductID jiná se budou lišit ve webových ovládacích prvcích používaných ke shromažďování informací o nových produktech.

Pokud chcete vytvořit rozhraní pro úpravy, zvolte odkaz Upravit šablony z inteligentní značky GridView. Pak v rozevíracím seznamu vyberte odpovídající pole s FooterTemplate a přetáhněte příslušný ovládací prvek z panelu nástrojů do Designer.

Přidání odpovídajícího rozhraní pro vkládání do zápatí každého pole s zápatíTemplate

Obrázek 9: Přidání příslušného rozhraní pro vkládání do jednotlivých polí FooterTemplate (kliknutím zobrazíte obrázek v plné velikosti)

Následující seznam s odrážkami obsahuje výčet polí GridView a určuje rozhraní pro vložení, které se má přidat:

  • ProductID Žádný.
  • ProductName přidejte textové pole a nastavte ho ID na NewProductName. Přidejte také ovládací prvek RequiredFieldValidator, abyste zajistili, že uživatel zadá hodnotu pro název nového produktu.
  • SupplierID Žádný.
  • CategoryID Žádný.
  • QuantityPerUnit přidejte TextBox a nastavte ho ID na NewQuantityPerUnit.
  • UnitPrice přidejte Textové pole s názvem NewUnitPrice a CompareValidator, které zajistí, že zadaná hodnota je hodnota měny větší než nebo rovna nule.
  • UnitsInStock použijte TextBox, jehož ID hodnota je nastavená na NewUnitsInStock. Zahrnout CompareValidator, který zajistí, že zadaná hodnota je celočíselná hodnota větší než nebo rovna nule.
  • UnitsOnOrder použijte TextBox, jehož ID hodnota je nastavená na NewUnitsOnOrder. Zahrnout CompareValidator, který zajistí, že zadaná hodnota je celočíselná hodnota větší než nebo rovna nule.
  • ReorderLevel použijte TextBox, jehož ID hodnota je nastavená na NewReorderLevel. Zahrnout CompareValidator, který zajistí, že zadaná hodnota je celočíselná hodnota větší než nebo rovna nule.
  • Discontinued přidejte CheckBox a nastavte ho ID na NewDiscontinued.
  • CategoryName přidejte DropDownList a nastavte ho ID na NewCategoryID. Vytvořte vazbu k novému objektu ObjectDataSource s názvem CategoriesDataSource a nakonfigurujte ho tak, aby používal metodu CategoriesBLL třídy s GetCategories() . Nechte uživatele DropDownList zobrazit ListItemCategoryName datové pole pomocí datových CategoryID polí jako jejich hodnot.
  • SupplierName přidejte dropDownList a nastavte ho ID na NewSupplierID. Vytvořte vazbu k novému objektu ObjectDataSource s názvem SuppliersDataSource a nakonfigurujte ho tak, aby používal metodu SuppliersBLL třídy s GetSuppliers() . Nechte uživatele DropDownList zobrazit ListItemCompanyName datové pole pomocí datových SupplierID polí jako jejich hodnot.

U každého z ověřovacích ovládacích prvků vymažte ForeColor vlastnost tak, aby FooterStyle se místo výchozí červené použila bílá barva popředí třídy CSS. Vlastnost použijte ErrorMessage také pro podrobný popis, ale nastavte ji Text na hvězdičku. Pokud chcete zabránit tomu, aby text ověřovacího ovládacího prvku způsobil zalomení rozhraní pro vkládání na dva řádky, nastavte FooterStyle vlastnost s Wrap na false pro každý z FooterTemplate s, které používají ověřovací ovládací prvek. Nakonec přidejte ovládací prvek ValidationSummary pod GridView a nastavte jeho ShowMessageBox vlastnost na true a jeho ShowSummary vlastnost na false.

Při přidávání nového produktu musíme zadat CategoryID a SupplierID. Tyto informace jsou zachyceny prostřednictvím rozevíracích seznamů v buňkách zápatí pro CategoryName pole a SupplierName . Rozhodl(a) jsem se použít tato pole na rozdíl od CategoryID polí a SupplierID TemplateFields, protože v datových řádcích mřížky má uživatel pravděpodobně větší zájem o zobrazení názvů kategorií a dodavatelů než jejich id hodnot. CategoryID Vzhledem k tomu, že hodnoty a SupplierID jsou nyní zachyceny v CategoryName rozhraních pro vkládání polí a SupplierName , můžeme odebrat CategoryID a SupplierID TemplateFields z Objekt GridView.

Podobně ProductID se nepoužívá při přidávání nového produktu, takže ProductID TemplateField lze odebrat také. Ponechme ProductID ale pole v mřížce. Kromě textových polí, rozevíracích seznamů, zaškrtávacích polí a ověřovacích ovládacích prvků, které tvoří rozhraní pro vkládání, budeme potřebovat také tlačítko Přidat, které po kliknutí provede logiku pro přidání nového produktu do databáze. V kroku 4 přidáme tlačítko Přidat do rozhraní pro vkládání v ProductID TemplateField s FooterTemplate.

Nebojte se vylepšit vzhled různých polí GridView. Můžete například chtít formátovat UnitPrice hodnoty jako měnu, zarovnat UnitsInStockpole , UnitsOnOrdera ReorderLevel doprava a aktualizovat HeaderText hodnoty polí TemplateFields.

Po vytvoření postupu vkládání rozhraní v FooterTemplate s, odebrání SupplierID, a CategoryID TemplateFields a vylepšení estetické mřížky prostřednictvím formátování a zarovnání TemplateFields by deklarativní značky GridView by měl vypadat podobně jako následující:

<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>

Při prohlížení v prohlížeči teď řádek zápatí GridView obsahuje dokončené rozhraní pro vkládání (viz Obrázek 10). V tomto okamžiku rozhraní pro vkládání neobsahuje způsob, jak uživatel označit, že zadal data pro nový produkt a chce vložit nový záznam do databáze. Také jsme ještě neřešili, jak se data zadaná do zápatí přeloží do nového záznamu v Products databázi. V kroku 4 se podíváme na to, jak do rozhraní pro vkládání zahrnout tlačítko Přidat a jak spustit kód při zpětném odeslání po kliknutí. Krok 5 ukazuje, jak vložit nový záznam pomocí dat ze zápatí.

Zápatí GridView poskytuje rozhraní pro přidání nového záznamu.

Obrázek 10: Zápatí GridView poskytuje rozhraní pro přidání nového záznamu (kliknutím zobrazíte obrázek v plné velikosti)

Krok 4: Zahrnutí tlačítka Přidat do vkládání rozhraní

Do rozhraní pro vkládání musíme zahrnout tlačítko Přidat, protože rozhraní pro vkládání řádků zápatí v současné době postrádá prostředky, které by uživateli mohly znamenat, že zadávání informací o novém produktu dokončilo. Můžete ho umístit do některého z existujících FooterTemplate s nebo pro tento účel přidat do mřížky nový sloupec. Pro účely tohoto kurzu umístíme tlačítko Přidat do ProductID pole TemplateField s FooterTemplate.

V Designer klikněte na odkaz Upravit šablony v inteligentní značce GridView a pak v rozevíracím seznamu zvolte ProductID pole sFooterTemplate. Přidejte do šablony webový ovládací prvek Button (nebo LinkButton nebo ImageButton, pokud chcete) a nastavte jeho ID na AddProduct, jeho CommandName hodnotu na Insert a jeho Text vlastnost na Add (Přidat), jak je znázorněno na obrázku 11.

Umístěte tlačítko Přidat do pole ProductID TemplateField s FooterTemplate

Obrázek 11: Umístěte tlačítko Přidat do ProductID šablonyPole FooterTemplate (kliknutím zobrazíte obrázek v plné velikosti)

Jakmile přidáte tlačítko Přidat, otestujte stránku v prohlížeči. Všimněte si, že po kliknutí na tlačítko Přidat s neplatnými daty v rozhraní pro vkládání dojde ke zkratování zpětného odeslání a ovládací prvek ValidationSummary indikuje neplatná data (viz Obrázek 12). Po zadání odpovídajících dat dojde po kliknutí na tlačítko Přidat k zpětnému odeslání. Do databáze se ale nepřidá žádný záznam. Abychom vložení skutečně provedli, budeme muset napsat trochu kódu.

Postback tlačítka přidat je zkratovaný, pokud jsou v rozhraní pro vkládání neplatná data

Obrázek 12: Postback tlačítka přidat je zkratovaný, pokud jsou v rozhraní pro vkládání neplatná data (kliknutím zobrazíte obrázek v plné velikosti).

Poznámka

Ověřovací ovládací prvky v rozhraní pro vkládání nebyly přiřazeny ověřovací skupině. To funguje správně, pokud je rozhraní pro vkládání jedinou sadou ověřovacích ovládacích prvků na stránce. Pokud však na stránce existují další ověřovací ovládací prvky (například ověřovací ovládací prvky v rozhraní pro úpravy mřížky), ověřovací ovládací prvky ve vlastnostech vkládání rozhraní a Přidat tlačítko ValidationGroup by měly být přiřazeny stejné hodnoty, aby se tyto ovládací prvky přidružily ke konkrétní ověřovací skupině. Další informace o rozdělení ověřovacích ovládacích prvků a tlačítek na stránce do ověřovacích skupin najdete v tématu Rozdělení ověřovacích ovládacích prvků v ASP.NET 2.0 .

Krok 5: Vložení nového záznamu doProductstabulky

Při využití předdefinovaných editačních funkcí GridView GridView automaticky zpracovává veškerou práci potřebnou k provedení aktualizace. Zejména při kliknutí na tlačítko Update zkopíruje hodnoty zadané z rozhraní pro úpravy do parametrů v kolekci ObjectDataSource UpdateParameters a spustí aktualizaci vyvoláním metody ObjectDataSource s Update() . Vzhledem k tomu, GridView neposkytuje takové integrované funkce pro vložení, musíme implementovat kód, který volá ObjectDataSource s Insert() metoda a zkopíruje hodnoty z vkládání rozhraní do ObjectDataSource s InsertParameters kolekce.

Tato logika vložení by se měla spustit po kliknutí na tlačítko Přidat. Jak je popsáno v kurzu Přidávání tlačítek a odpovídání na ně v gridview , při kliknutí na Tlačítko, LinkButton nebo ImageButton v objektu GridView se událost GridView aktivuje RowCommand při zpětném odeslání. Tato událost se aktivuje bez ohledu na to, jestli byla explicitně přidána button, LinkButton nebo ImageButton, například tlačítko Přidat v řádku zápatí, nebo pokud byla automaticky přidána objektem GridView (například LinkButtons v horní části každého sloupce, když je vybrána možnost Povolit řazení, nebo LinkButtons ve stránkovacím rozhraní, pokud je vybrána možnost Povolit stránkování).

Proto abychom mohli reagovat na to, že uživatel klikne na tlačítko Přidat, musíme pro událost GridView RowCommand vytvořit obslužnou rutinu události. Vzhledem k tomu, že tato událost se aktivuje při každém kliknutí na tlačítko Button, LinkButton nebo ImageButton v objektu GridView, je důležité, abychom pokračovali v vkládání logiky pouze v případě, že CommandName se vlastnost předaná do obslužné rutiny události mapuje na CommandName hodnotu tlačítka Přidat ( Insert ). Navíc bychom měli pokračovat pouze v případě, že ověřovací ovládací prvky hlásí platná data. Pro tuto možnost vytvořte obslužnou rutinu RowCommand události s následujícím kódem:

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...
    }
}

Poznámka

Možná vás zajímá, proč obslužná rutina události obtěžuje Page.IsValid kontrolu vlastnosti . Koneckonců, nebude postback potlačen, pokud jsou v rozhraní pro vkládání k dispozici neplatná data? Tento předpoklad je správný, pokud uživatel nezakázel JavaScript nebo podnikl kroky k obcházení logiky ověřování na straně klienta. Stručně řečeno, člověk by se nikdy neměl spoléhat výhradně na ověřování na straně klienta; Kontrola platnosti na straně serveru by se měla vždy provést před zahájením práce s daty.

V kroku 1 jsme vytvořili ProductsDataSource ObjectDataSource tak, aby jeho Insert() metoda byla mapována na metodu ProductsBLL třídy s AddProduct . Pokud chcete vložit nový záznam do Products tabulky, můžeme jednoduše vyvolat metodu ObjectDataSource s 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();
    }
}

Teď, když Insert() byla metoda vyvolána, zbývá jen zkopírovat hodnoty z rozhraní pro vkládání do parametrů předaných ProductsBLL metodě třídy s AddProduct . Jak jsme viděli v kurzu Zkoumání událostí spojených s vkládáním, aktualizací a odstraňováním , můžete toho dosáhnout prostřednictvím události ObjectDataSource Inserting . V případě, že Inserting potřebujeme programově odkazovat na ovládací prvky z Products řádku zápatí GridView a přiřadit jejich hodnoty kolekci e.InputParameters . Pokud uživatel vynechá hodnotu, například ponechá ReorderLevel TextBox prázdný, musíme zadat, že hodnota vložená do databáze by měla být NULL. Vzhledem k tomu, že AddProducts metoda přijímá typy s možnou hodnotou null pro pole databáze s možnou hodnotou null, jednoduše použijte typ s možnou hodnotou null a nastavte jeho hodnotu na null v případě, že je uživatelský vstup vynechán.

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;
}

Po dokončení obslužné Inserting rutiny události je možné do Products databázové tabulky přidat nové záznamy prostřednictvím řádku zápatí GridView. Zkuste přidat několik nových produktů.

Vylepšení a přizpůsobení operace přidání

V současné době se kliknutím na tlačítko Přidat přidá nový záznam do databázové tabulky, ale nezobrazí se žádná vizuální zpětná vazba, že se záznam úspěšně přidal. V ideálním případě by ovládací prvek Label Web nebo okno upozornění na straně klienta uživatele informovalo, že vložení bylo úspěšně dokončeno. Nechávám to jako cvičení pro čtenáře.

Objekt GridView použitý v tomto kurzu nepoužije žádné pořadí řazení na uvedené produkty, ani neumožňuje koncovému uživateli řadit data. V důsledku toho jsou záznamy seřazené tak, jak jsou v databázi, podle pole primárního klíče. Vzhledem k tomu, že každý nový záznam má ProductID hodnotu větší než ten poslední, při každém přidání nového produktu se přihodí na konec mřížky. Proto můžete chtít po přidání nového záznamu automaticky odeslat uživatele na poslední stránku GridView. Toho lze dosáhnout přidáním následujícího řádku kódu za volání ProductsDataSource.Insert() v obslužné rutině RowCommand události, který označuje, že uživatel musí být odeslán na poslední stránku po vytvoření vazby dat s objektem GridView:

// Indicate that the user needs to be sent to the last page
SendUserToLastPage = true;

SendUserToLastPage je logická proměnná na úrovni stránky, které je na začátku přiřazena hodnota false. Pokud je v obslužné rutině SendUserToLastPage události GridView DataBound false, vlastnost se aktualizuje tak, PageIndex aby se uživatel odeslal na poslední stránku.

protected void Products_DataBound(object sender, EventArgs e)
{
    // Send user to last page of data, if needed
    if (SendUserToLastPage)
        Products.PageIndex = Products.PageCount - 1;
}

Důvodem, proč PageIndex je vlastnost nastavená v DataBound obslužné rutině události (na rozdíl od RowCommand obslužné rutiny události), je, že při RowCommand spuštění obslužné rutiny události jsme ještě přidali nový záznam do Products databázové tabulky. Proto poslední index stránky (PageCount - 1) v obslužné RowCommand rutině události představuje index poslední stránky před přidání nového produktu. U většiny přidávaných produktů je index poslední stránky stejný po přidání nového produktu. Pokud ale přidaný produkt způsobí nový index poslední stránky, pokud nesprávně aktualizujeme PageIndex v RowCommand obslužné rutině události, přejdeme na předposlední stránku (index poslední stránky před přidáním nového produktu) místo na index nové poslední stránky. DataBound Vzhledem k tomu, že se obslužná rutina události aktivuje po přidání nového produktu a data se odskočí do mřížky, nastavením vlastnosti tam víme, PageIndex že získáváme správný index poslední stránky.

A konečně GridView použitý v tomto kurzu je poměrně široký kvůli počtu polí, která musí být shromážděna pro přidání nového produktu. Vzhledem k této šířce může být vhodnější svislé rozložení DetailsView. Celkovou šířku objektu GridView je možné snížit shromažďováním menšího počtu vstupů. Možná nemusíme shromažďovat UnitsOnOrderpole , UnitsInStocka ReorderLevel při přidávání nového produktu. V takovém případě by se tato pole mohla odebrat z ovládacího prvku GridView.

K úpravě shromažďovaných dat můžeme použít jeden ze dvou přístupů:

  • Pokračujte v AddProduct používání metody, která očekává hodnoty pro UnitsOnOrderpole , UnitsInStocka ReorderLevel . V obslužné rutině Inserting události zadejte pevně zakódované výchozí hodnoty, které se mají použít pro tyto vstupy, které byly odebrány z rozhraní pro vkládání.
  • Vytvořte nové přetížení AddProduct metody ve ProductsBLL třídě , která nepřijímá vstupy pro UnitsOnOrderpole , UnitsInStocka ReorderLevel . Potom na stránce ASP.NET nakonfigurujte ObjectDataSource tak, aby používal toto nové přetížení.

Obě možnosti budou fungovat stejně. V minulých kurzech jsme použili druhou možnost, která pro metodu ProductsBLL třídy s UpdateProduct vytvořila několik přetížení.

Souhrn

GridView nemá integrované funkce vkládání, které se nacházejí v DetailsView a FormView, ale s trochou úsilí lze do řádku zápatí přidat rozhraní pro vkládání. Pokud chcete zobrazit řádek zápatí v objektu GridView, jednoduše nastavte jeho ShowFooter vlastnost na true. Obsah řádku zápatí lze přizpůsobit pro každé pole převedením pole na TemplateField a přidáním rozhraní pro vkládání do FooterTemplatepole . Jak jsme viděli v tomto kurzu, FooterTemplate může obsahovat tlačítka, textová pole, rozevírací seznamy, zaškrtávací políčka, ovládací prvky zdroje dat pro naplnění webových ovládacích prvků řízených daty (například DropDownLists) a ověřovací ovládací prvky. Spolu s ovládacími prvky pro shromažďování vstupu uživatele je potřeba tlačítko Přidat, LinkButton nebo ImageButton.

Po kliknutí na tlačítko Přidat se vyvolá metoda ObjectDataSource s Insert() pro spuštění pracovního postupu vkládání. ObjectDataSource pak zavolá nakonfigurovanou metodu ProductsBLL insert (metoda třídy s AddProduct v tomto kurzu). Před vyvoláním metody insert musíme zkopírovat hodnoty z gridView s do kolekce ObjectDataSource s InsertParameters . Toho lze dosáhnout programovým odkazem na vkládání rozhraní Webové ovládací prvky v obslužné rutině události ObjectDataSource Inserting .

Tento kurz zakončí náš pohled na techniky pro vylepšení vzhledu objektu GridView. V další sadě kurzů se dozvíte, jak pracovat s binárními daty, jako jsou obrázky, soubory PDF, Word dokumenty atd., a s ovládacími prvky pro webová data.

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .

Zvláštní poděkování

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavní revidující pro tento kurz byla Bernadette Leigh. Chcete si projít moje nadcházející články na WEBU MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.comadresu .