Sdílet prostřednictvím


Zkoumání událostí spojených s vložením, aktualizací a odstraněním (VB)

Scott Mitchell

Stáhnout PDF

V tomto kurzu prozkoumáme použití událostí, ke kterým dochází před, během a po vložení, aktualizaci nebo odstranění operace ASP.NET webového ovládacího prvku dat. Uvidíme také, jak přizpůsobit rozhraní pro úpravy tak, aby se aktualizovala jenom podmnožina polí produktu.

Úvod

Při použití integrovaných vkládání, úprav nebo odstraňování funkcí ovládacích prvků GridView, DetailsView nebo FormView se po dokončení procesu přidání nového záznamu nebo aktualizace nebo odstranění existujícího záznamu překládá celá řada kroků. Jak jsme probrali v předchozím kurzu, když je řádek upraven v GridView tlačítko Upravit je nahrazena tlačítky Update a Cancel a BoundFields se změní na textová pole. Jakmile koncový uživatel aktualizuje data a klikne na Aktualizovat, provede se v postbacku následující kroky:

  1. GridView naplní objekt ObjectDataSource UpdateParameters jedinečným identifikačním polem upraveného záznamu (prostřednictvím DataKeyNames vlastnosti) spolu s hodnotami zadanými uživatelem.
  2. GridView vyvolá jeho ObjectDataSource Update() metoda, která následně vyvolá příslušnou metodu v podkladovém objektu (ProductsDAL.UpdateProductv našem předchozím kurzu).
  3. Podkladová data, která teď zahrnují aktualizované změny, se přepojují do GridView.

Během této posloupnosti kroků se aktivuje řada událostí, což nám umožní vytvořit obslužné rutiny událostí, abychom tam, kde je to potřeba, přidali vlastní logiku. Například před krokem 1 se aktivuje událost GridView RowUpdating . V tuto chvíli můžeme žádost o aktualizaci zrušit, pokud dojde k nějaké chybě ověření. Update() Při vyvolání metody se aktivuje událost ObjectDataSourceUpdating, která poskytuje příležitost přidat nebo přizpůsobit hodnoty libovolného objektu UpdateParameters. Po dokončení provádění metody základního objektu ObjectDataSource je vyvolána událost ObjectDataSource Updated . Obslužná rutina události může Updated zkontrolovat podrobnosti o operaci aktualizace, například počet ovlivněných řádků a zda došlo k výjimce. Nakonec se po kroku 2 aktivuje událost GridView RowUpdated . Obslužná rutina události pro tuto událost může prozkoumat další informace o právě provedené operaci aktualizace.

Obrázek 1 znázorňuje tuto řadu událostí a kroků při aktualizaci objektu GridView. Vzor události na obrázku 1 není jedinečný pro aktualizaci pomocí GridView. Vložení, aktualizace nebo odstranění dat z objektu GridView, DetailsView nebo FormView předem vygeneruje stejnou sekvenci událostí na úrovni před a po úrovni pro ovládací prvek Data Web i ObjectDataSource.

Při aktualizaci dat v objektu GridView se aktivuje řada před a po událostech.

Obrázek 1: Při aktualizaci dat v Objektu GridView (kliknutím zobrazíte obrázek s plnou velikostí)

V tomto kurzu prozkoumáme použití těchto událostí k rozšíření integrovaných možností vkládání, aktualizace a odstraňování funkcí ASP.NET webových ovládacích prvků dat. Uvidíme také, jak přizpůsobit rozhraní pro úpravy tak, aby se aktualizovala jenom podmnožina polí produktu.

Krok 1: Aktualizace produktůProductNameaUnitPricepolí

V rozhraních pro úpravy z předchozího kurzu bylo nutné zahrnout všechna pole produktů, která nebyla určena jen pro čtení. Pokud bychom odebrali pole z objektu GridView – řekněme QuantityPerUnit – při aktualizaci dat, ovládací prvek web dat nenastavil hodnotu ObjectDataSource QuantityPerUnit UpdateParameters . ObjectDataSource by pak předal hodnotu Nothing do UpdateProduct metody BLL (Business Logic Layer), která by změnila sloupec upraveného záznamu QuantityPerUnit databáze na NULL hodnotu. Podobně platí, že pokud je z rozhraní pro úpravy odebráno povinné pole, ProductNameaktualizace selže s výjimkou Sloupec ProductName nepovoluje hodnoty null. Důvodem tohoto chování bylo to, že ObjectDataSource byl nakonfigurován tak, aby volal ProductsBLL metodu třídy UpdateProduct , která očekávala vstupní parametr pro každé pole produktu. Kolekce ObjectDataSource UpdateParameters proto obsahovala parametr pro každý ze vstupních parametrů metody.

Pokud chceme poskytnout ovládací prvek webu dat, který koncovému uživateli umožňuje aktualizovat pouze podmnožinu polí, musíme buď programově nastavit chybějící UpdateParameters hodnoty v obslužné rutině události ObjectDataSource Updating , nebo vytvořit a volat metodu BLL, která očekává pouze podmnožinu polí. Pojďme se podívat na tento druhý přístup.

Konkrétně vytvoříme stránku, která zobrazí pouze ProductName pole a UnitPrice pole v upravitelném objektu GridView. Toto rozhraní pro úpravy GridView umožní uživateli aktualizovat pouze dvě zobrazená pole ProductName a UnitPrice. Vzhledem k tomu, že toto rozhraní pro úpravy poskytuje pouze podmnožinu polí produktu, musíme buď vytvořit ObjectDataSource, který používá existující metodu UpdateProduct BLL a má chybějící hodnoty pole produktu nastavené programově v obslužné Updating rutině události, nebo musíme vytvořit novou metodu BLL, která očekává pouze podmnožinu polí definovaných v GridView. V tomto kurzu použijeme druhou možnost a vytvoříme přetížení UpdateProduct metody, která přebírá pouze tři vstupní parametry: productName, unitPricea productID:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Update, False)> _
    Public Function UpdateProduct(productName As String, _
        unitPrice As Nullable(Of Decimal), productID As Integer) _
        As Boolean

    Dim products As Northwind.ProductsDataTable = _
        Adapter.GetProductByProductID(productID)

    If products.Count = 0 Then
        Return False
    End If

    Dim product As Northwind.ProductsRow = products(0)

    product.ProductName = productName
    If Not unitPrice.HasValue Then
        product.SetUnitPriceNull()
    Else
        product.UnitPrice = unitPrice.Value
    End If

    Dim rowsAffected As Integer = Adapter.Update(product)

    Return rowsAffected = 1
End Function

Podobně jako původní UpdateProduct metoda začíná toto přetížení tím, že zkontroluje, zda v databázi existuje produkt se zadaným ProductID. Pokud ne, vrátí Falsese , což znamená, že požadavek na aktualizaci informací o produktu selhal. Jinak aktualizuje hodnoty a UnitPrice pole existujícího záznamu ProductName produktu odpovídajícím způsobem a potvrdí aktualizaci voláním metody TableAdapter Update() a předá instanciProductsRow.

S tímto doplňkem naší ProductsBLL třídy jsme připraveni vytvořit zjednodušené rozhraní GridView. DataModificationEvents.aspx Otevřete složku ve EditInsertDelete složce a přidejte na stránku objekt GridView. Vytvořte nový ObjectDataSource a nakonfigurujte ji tak, aby používala ProductsBLL třídu s mapováním metody Select() na GetProducts a jeho Update() metod mapování na UpdateProduct přetížení, které přebírá pouze productName, unitPricea productID vstupní parametry. Obrázek 2 znázorňuje průvodce vytvořením zdroje dat při mapování metody ObjectDataSource Update() na ProductsBLL přetížení nové UpdateProduct metody třídy.

Mapovat ObjectDataSource Update() Metoda na New UpdateProduct Přetížení

Obrázek 2: Mapování metody ObjectDataSource Update() na nové UpdateProduct přetížení (kliknutím zobrazíte obrázek plné velikosti)

Vzhledem k tomu, že náš příklad bude zpočátku potřebovat možnost upravovat data, ale ne vkládat nebo odstraňovat záznamy, chvíli naznačte, že ObjektDataSource Insert() a Delete() metody by neměly být mapovány na žádné metody ProductsBLL třídy tak, že přejdete na karty INSERT a DELETE a v rozevíracím seznamu zvolíte (Žádné).

V rozevíracím seznamu pro karty INSERT a DELETE zvolte (Žádné).

Obrázek 3: V rozevíracím seznamu karet INSERT a DELETE (Kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení tohoto průvodce zaškrtněte políčko Povolit úpravy z inteligentní značky GridView.

Po dokončení Průvodce vytvořením zdroje dat a vazbou, která je s GridView, Visual Studio vytvořil deklarativní syntaxi pro oba ovládací prvky. Přejděte do zobrazení Zdroj a prozkoumejte deklarativní kód ObjectDataSource, který je znázorněn níže:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Vzhledem k tomu, že neexistují žádná mapování pro ObjectDataSource Insert() a Delete() metody, neexistují žádné InsertParameters nebo DeleteParameters oddíly. Navíc vzhledem k tomu Update() , že metoda je namapována na UpdateProduct přetížení metody, která přijímá pouze tři vstupní parametry, UpdateParameters oddíl má pouze tři Parameter instance.

Všimněte si, že vlastnost ObjectDataSource OldValuesParameterFormatString je nastavena na original_{0}. Tato vlastnost je automaticky nastavena sadou Visual Studio při použití Průvodce konfigurací zdroje dat. Vzhledem k tomu, že naše metody BLL neočekávají předání původní ProductID hodnoty, odeberte toto přiřazení vlastnosti zcela z deklarativní syntaxe ObjectDataSource.

Poznámka:

Pokud jednoduše vymažete OldValuesParameterFormatString hodnotu vlastnosti z okno Vlastnosti v návrhovém zobrazení, vlastnost bude stále existovat v deklarativní syntaxi, ale bude nastavena na prázdný řetězec. Buď odeberte vlastnost zcela z deklarativní syntaxe, nebo z okno Vlastnosti nastavte hodnotu na výchozí hodnotu {0}.

Zatímco ObjectDataSource má UpdateParameters pouze pro název produktu, cenu a ID, Visual Studio přidala BoundField nebo CheckBoxField do GridView pro každé pole produktu.

GridView obsahuje BoundField nebo CheckBoxField pro každou pole produktu.

Obrázek 4: Objekt GridView obsahuje pole BoundField nebo CheckBoxField pro jednotlivá pole produktu (kliknutím zobrazíte obrázek v plné velikosti).

Když koncový uživatel upraví produkt a klikne na tlačítko Aktualizovat, GridView zobrazí výčet polí, která nebyla určena jen pro čtení. Potom nastaví hodnotu odpovídajícího parametru v kolekci ObjectDataSource UpdateParameters na hodnotu zadaná uživatelem. Pokud neexistuje odpovídající parametr, GridView ho přidá do kolekce. Proto pokud naše GridView obsahuje BoundFields a CheckBoxFields pro všechna pole produktu, ObjectDataSource skončí vyvolá UpdateProduct přetížení, které přebírá všechny tyto parametry, i když fakt, že deklarativní kód ObjectDataSource určuje pouze tři vstupní parametry (viz obrázek 5). Podobně platí, že pokud v objektu GridView existuje nějaká kombinace polí produktu, která nejsou určená jen pro čtení, která neodpovídá vstupním parametrům přetížení, při pokusu UpdateProduct o aktualizaci se vyvolá výjimka.

GridView přidá parametry do kolekce UpdateParameters ObjectDataSource.

Obrázek 5: GridView přidá parametry do kolekce ObjectDataSource UpdateParameters (kliknutím zobrazíte obrázek s plnou velikostí).

Abychom zajistili, že ObjectDataSource vyvolá UpdateProduct přetížení, které přebírá pouze název produktu, cenu a ID, musíme omezit GridView na upravitelná pole pouze pro ProductName UnitPricea . Toho lze dosáhnout odebráním ostatních BoundFields a CheckBoxFields nastavením vlastnosti těchto ostatních polí ReadOnly na True, nebo pomocí některé kombinace těchto dvou. Pro účely tohoto kurzu jednoduše odebereme všechna pole GridView kromě ProductName polí a UnitPrice BoundFields, po kterých deklarativní revize GridView bude vypadat takto:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

I když UpdateProduct přetížení očekává tři vstupní parametry, máme v objektu GridView pouze dva BoundFields. Důvodem je to, že productID vstupní parametr je hodnota primárního DataKeyNames klíče a předána prostřednictvím hodnoty vlastnosti pro upravený řádek.

Naše GridView spolu s UpdateProduct přetížením umožňuje uživateli upravit pouze název a cenu produktu, aniž by se ztratila některá z ostatních polí produktu.

Rozhraní umožňuje úpravy pouze názvu a ceny produktu.

Obrázek 6: Rozhraní umožňuje úpravy pouze názvu a ceny produktu (kliknutím zobrazíte obrázek v plné velikosti).

Poznámka:

Jak je popsáno v předchozím kurzu, je důležité, aby byl stav zobrazení GridView povolen (výchozí chování). Pokud nastavíte GridView s EnableViewState vlastnost false, spustíte riziko, že souběžní uživatelé neúmyslně odstraní nebo upraví záznamy.

UnitPriceVylepšení formátování

I když příklad GridView zobrazený na obrázku 6 funguje, UnitPrice pole není vůbec formátováno, což vede k zobrazení ceny, která neobsahuje symboly měny a má čtyři desetinná místa. Chcete-li použít formátování měny pro neupravitelné řádky, jednoduše nastavte UnitPrice vlastnost BoundField DataFormatString na {0:c} hodnotu a její HtmlEncode vlastnost na False.

Odpovídajícím způsobem nastavte vlastnosti DataFormatString a HtmlEncode hodnoty UnitPrice.

Obrázek 7: Nastavení UnitPricevlastnosti a HtmlEncode vlastnosti DataFormatString odpovídajícím způsobem (kliknutím zobrazíte obrázek s plnou velikostí)

Při této změně formátuje neupravitelné řádky cenu jako měnu; upravený řádek ale stále zobrazuje hodnotu bez symbolu měny a se čtyřmi desetinnými místy.

Neupravitelné řádky jsou teď formátované jako hodnoty měny.

Obrázek 8: Neupravitelné řádky jsou teď formátované jako hodnoty měny (kliknutím zobrazíte obrázek plné velikosti).

Pokyny k formátování zadané ve DataFormatString vlastnosti lze použít pro rozhraní pro úpravy nastavením vlastnosti BoundField ApplyFormatInEditMode na True (výchozí hodnota je False). Nastavte tuto vlastnost na Truehodnotu .

Nastavení Vlastnosti ApplyFormatInEditMode UnitPrice BoundField na Hodnotu True

Obrázek 9: Nastavení UnitPrice vlastnosti BoundField ApplyFormatInEditMode na True (Kliknutím zobrazíte obrázek v plné velikosti)

Při této změně je hodnota UnitPrice zobrazená v upraveném řádku také formátována jako měna.

Snímek obrazovky Objektu GridView zobrazující hodnotu UnitPrice upraveného řádku formátovanou jako měnu

Obrázek 10: Hodnota upraveného UnitPrice řádku je teď formátovaná jako měna (kliknutím zobrazíte obrázek v plné velikosti).

Aktualizace produktu pomocí symbolu měny v textovém poli, jako je například 19,00 USD, však vyvolá FormatExceptionchybu . Když se GridView pokusí přiřadit uživatelem zadané hodnoty do kolekce ObjectDataSource UpdateParameters , nemůže převést UnitPrice řetězec "$19,00" na Decimal požadovaný parametr (viz obrázek 11). Abychom to mohli napravit, můžeme vytvořit obslužnou rutinu události pro událost GridView RowUpdating a nechat ji parsovat uživatelem zadaný UnitPrice jako měna formátovaný Decimal.

Událost GridView RowUpdating přijímá jako druhý parametr objekt typu GridViewUpdateEventArgs, který obsahuje NewValues slovník jako jednu z jeho vlastností, která obsahuje hodnoty zadané uživatelem připravené k přiřazení ke kolekci ObjectDataSource UpdateParameters . Existující UnitPrice hodnotu v NewValues kolekci můžeme přepsat desetinnou hodnotou parsovanou pomocí formátu měny následujícími řádky kódu v obslužné rutině RowUpdating události:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating
    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    End If
End Sub

Pokud uživatel zadal UnitPrice hodnotu (například 19,00 Kč), tato hodnota se přepíše desetinnou hodnotou vypočítanou funkcí Decimal.Parse a parsuje hodnotu jako měnu. Tím se správně parsuje desetinné číslo v případě symbolů měny, čárk, desetinných míst atd. a použije výčet NumberStyles v oboru názvů System.Globalization .

Obrázek 11 ukazuje problém způsobený symboly měny v zadaném uživateli UnitPricespolu s tím, jak lze obslužnou rutinu události GridView RowUpdating použít k správné analýze takového vstupu.

Diagram znázorňující, jak ObjectDataSource zpracovává pole UnitPrice a jak obslužná rutina události RowUpdate objektu GridView převede řetězec na desetinné číslo.

Obrázek 11: Hodnota upraveného UnitPrice řádku je teď formátovaná jako měna (kliknutím zobrazíte obrázek v plné velikosti).

Krok 2: ZakázáníNULL UnitPrices

I když je databáze nakonfigurovaná tak, aby umožňovala NULL hodnoty ve Products sloupci tabulky UnitPrice , můžeme uživatelům, kteří navštíví tuto konkrétní stránku, zabránit zadání NULL UnitPrice hodnoty. To znamená, že pokud se uživateli nepodaří zadat UnitPrice hodnotu při úpravě řádku produktu, a ne uložit výsledky do databáze, kterou chceme zobrazit zprávu informující uživatele, že prostřednictvím této stránky musí mít všechny upravené produkty zadanou cenu.

Objekt GridViewUpdateEventArgs předaný do obslužné rutiny události GridView RowUpdating obsahuje Cancel vlastnost, která, pokud je nastavena na True, ukončí proces aktualizace. Pojďme rozšířit obslužnou rutinu RowUpdating události tak, aby True byla nastavena e.Cancel a zobrazena zpráva vysvětlující, proč má UnitPrice hodnota v NewValues kolekci hodnotu Nothing.

Začněte přidáním ovládacího prvku Label Web na stránku s názvem MustProvideUnitPriceMessage. Tento ovládací prvek Popisek se zobrazí, pokud uživatel při aktualizaci produktu nezadá UnitPrice hodnotu. Nastavte vlastnost Popisek Text na "Musíte zadat cenu produktu". Vytvořil(a) jsem také novou třídu CSS s Styles.css názvem Warning s následující definicí:

.Warning
{
    color: Red;
    font-style: italic;
    font-weight: bold;
    font-size: x-large;
}

Nakonec nastavte vlastnost Popisek CssClass na Warninghodnotu . V tomto okamžiku by návrhář měl zobrazit zprávu upozornění červenou, tučně, kurzívou, extra velkou velikost písma nad objektem GridView, jak je znázorněno na obrázku 12.

Nad Objekt GridView byl přidán popisek.

Obrázek 12: Nad objekt GridView byl přidán popisek (kliknutím zobrazíte obrázek v plné velikosti).

Ve výchozím nastavení by tento popisek měl být skrytý, takže jeho vlastnost nastavte Visible v False obslužné rutině Page_Load události:

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    MustProvideUnitPriceMessage.Visible = False
End Sub

Pokud se uživatel pokusí aktualizovat produkt bez zadání UnitPrice, chceme aktualizaci zrušit a zobrazit popisek upozornění. Rozšiřte obslužnou rutinu RowUpdating události GridView následujícím způsobem:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating

    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    Else
        MustProvideUnitPriceMessage.Visible = True

        e.Cancel = True
    End If
End Sub

Pokud se uživatel pokusí produkt uložit bez zadání ceny, aktualizace se zruší a zobrazí se užitečná zpráva. I když databáze (a obchodní logika) umožňuje NULL UnitPrice s, tato konkrétní ASP.NET stránka ne.

Uživatel nemůže ponechat jednotkovou cenu prázdnou.

Obrázek 13: Uživatel nemůže ponechat UnitPrice prázdné (kliknutím zobrazíte obrázek s plnou velikostí)

Zatím jsme viděli, jak pomocí události GridView RowUpdating programově změnit hodnoty parametrů přiřazené ke kolekci ObjectDataSource UpdateParameters a jak zrušit proces aktualizace úplně. Tyto koncepty se přenesou do ovládacích prvků DetailsView a FormView a vztahují se také na vkládání a odstraňování.

Tyto úlohy lze provádět také na úrovni ObjectDataSource prostřednictvím obslužných rutin událostí pro své Inserting, Updatinga Deleting události. Tyto události se aktivují před vyvoláním přidružené metody podkladového objektu a poskytují poslední příležitost ke změně kolekce vstupních parametrů nebo zrušení operace přímo. Obslužné rutiny událostí pro tyto tři události jsou předány objekt typu ObjectDataSourceMethodEventArgs , který má dvě vlastnosti zájmu:

  • Zrušení, které, pokud je nastaveno na True, zruší prováděné operace.
  • InputParameters, což je kolekce InsertParameters, UpdateParametersnebo DeleteParameters, v závislosti na tom, zda obslužná rutina události je pro Inserting, Updatingnebo Deleting událost

Abychom si ukázali práci s hodnotami parametrů na úrovni ObjectDataSource, zahrňme na naší stránce PodrobnostiView, která uživatelům umožňuje přidat nový produkt. Tento DetailsView se použije k poskytnutí rozhraní pro rychlé přidání nového produktu do databáze. Pokud chcete zachovat konzistentní uživatelské rozhraní při přidávání nového produktu, umožníme uživateli zadat pouze hodnoty pro pole ProductName a UnitPrice pole. Ve výchozím nastavení se hodnoty, které nejsou zadané v rozhraní pro vkládání DetailsView, nastaví na NULL hodnotu databáze. Událost ObjectDataSource Inserting ale můžeme použít k vložení různých výchozích hodnot, jak uvidíme krátce.

Krok 3: Poskytnutí rozhraní pro přidání nových produktů

Přetáhněte objekt DetailsView z panelu nástrojů na Návrhář nad Objekt GridView, vymažte jeho Height a Width vlastnosti a vytvořte vazbu na ObjektDataSource, který již na stránce existuje. Tím přidáte BoundField nebo CheckBoxField pro každé pole produktu. Vzhledem k tomu, že chceme tuto detailsView použít k přidání nových produktů, musíme z inteligentní značky zkontrolovat možnost Povolit vložení; Neexistuje však žádná taková možnost, protože metoda ObjectDataSource Insert() není mapována na metodu ProductsBLL ve třídě (vzpomeňte si, že jsme toto mapování nastavili na (None) při konfiguraci zdroje dat viz obrázek 3).

Pokud chcete konfigurovat ObjectDataSource, vyberte z inteligentní značky odkaz Konfigurovat zdroj dat a spusťte průvodce. První obrazovka umožňuje změnit základní objekt ObjectDataSource je vázán na; nechte ji nastavenou na ProductsBLL. Na další obrazovce se zobrazí mapování z metod ObjectDataSource na podkladový objekt. I když jsme explicitně uvedli, že Insert() metody a Delete() metody by neměly být namapovány na žádné metody, pokud přejdete na karty INSERT a DELETE, uvidíte, že mapování je tam. Důvodem je to, že ProductsBLL's AddProduct a DeleteProduct metody používají DataObjectMethodAttribute atribut k označení, že jsou výchozí metody pro Insert() a Delete(), v uvedeném pořadí. Průvodce ObjectDataSource je proto vybere při každém spuštění průvodce, pokud není explicitně zadána nějaká jiná hodnota.

Ponechte metodu Insert() odkazující na metodu AddProduct , ale znovu nastavte rozevírací seznam karty DELETE na (Žádné).

Nastavení rozevíracího seznamu karty INSERT na metodu AddProduct

Obrázek 14: Nastavení rozevíracího seznamu karty INSERT na metodu AddProduct (kliknutím zobrazíte obrázek s plnou velikostí)

Nastavení rozevíracího seznamu na kartě DELETE na (žádné)

Obrázek 15: Nastavení rozevíracího seznamu karty DELETE na (Žádné) (kliknutím zobrazíte obrázek s plnou velikostí)

Po provedení těchto změn se deklarativní syntaxe ObjectDataSource rozšíří tak, aby zahrnovala InsertParameters kolekci, jak je znázorněno níže:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
    InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
    <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>

Znovu spustit průvodce přidaný OldValuesParameterFormatString zpět vlastnost. Než tuto vlastnost vymažete, nastavíte ji na výchozí hodnotu ({0}) nebo ji úplně odeberete z deklarativní syntaxe.

Když ObjectDataSource poskytuje možnosti vkládání, inteligentní značka DetailsView teď bude obsahovat zaškrtávací políčko Povolit vložení; vraťte se do Návrháře a zaškrtněte tuto možnost. Dále pare down the DetailsView tak, aby má pouze dva BoundFields - ProductName a UnitPrice - a CommandField. V tomto okamžiku by deklarativní syntaxe DetailsView měla vypadat takto:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
        <asp:CommandField ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

Obrázek 16 ukazuje tuto stránku při prohlížení v prohlížeči v tomto okamžiku. Jak vidíte, DetailsView uvádí název a cenu prvního produktu (Chai). Chceme ale vložit rozhraní, které uživateli umožňuje rychle přidat nový produkt do databáze.

DetailsView se aktuálně vykresluje v režimu jen pro čtení.

Obrázek 16: Objekt DetailsView je aktuálně vykreslen v režimu jen pro čtení (kliknutím zobrazíte obrázek v plné velikosti).

Abychom mohli zobrazit DetailsView v režimu vložení, musíme nastavit DefaultMode vlastnost na Inserting. Tím se při prvním návštěvě vykreslí DetailsView v režimu vložení a po vložení nového záznamu ho tam zachová. Jak ukazuje obrázek 17, takový DetailsView poskytuje rychlé rozhraní pro přidání nového záznamu.

DetailsView poskytuje rozhraní pro rychlé přidání nového produktu.

Obrázek 17: DetailsView poskytuje rozhraní pro rychlé přidání nového produktu (kliknutím zobrazíte obrázek v plné velikosti).

Když uživatel zadá název a cenu produktu (například "Acme Water" a 1,99, jak je znázorněno na obrázku 17) a klikne na Vložit, postback se začne a pracovní postup vložení začne, což bude komplikovat v novém záznamu o produktu, který se přidá do databáze. DetailsView udržuje své vložené rozhraní a GridView se automaticky přepojuje do svého zdroje dat, aby zahrnoval nový produkt, jak je znázorněno na obrázku 18.

Produkt

Obrázek 18: Produkt "Acme Water" byl přidán do databáze

I když GridView na obrázku 18 nezobrazuje, pole produktu chybí z rozhraní CategoryIDDetailsView , SupplierIDa QuantityPerUnittak dále jsou přiřazeny NULL hodnoty databáze. Můžete to zobrazit provedením následujících kroků:

  1. Přechod do Průzkumníka serveru v sadě Visual Studio
  2. NORTHWND.MDF Rozšíření uzlu databáze
  3. Klikněte pravým tlačítkem myši na Products uzel databázové tabulky.
  4. Výběr možnosti Zobrazit data tabulky

Zobrazí se seznam všech záznamů v Products tabulce. Jak ukazuje obrázek 19, všechny sloupce nového produktu jiné než ProductIDa ProductNameUnitPrice mají NULL hodnoty.

Pole produktu nezadaná v DetailsView jsou přiřazené hodnoty NULL.

Obrázek 19: Pole produktů nezadaná v detailsView jsou přiřazené NULL hodnoty (kliknutím zobrazíte obrázek v plné velikosti).

Můžeme chtít zadat jinou výchozí hodnotu než NULL pro jednu nebo více těchto hodnot sloupců, a to buď proto, že NULL není nejlepší výchozí možností, nebo protože samotný databázový sloupec nepovoluje NULL . Abychom toho dosáhli, můžeme nastavit hodnoty parametrů kolekce DetailsView InputParameters prostřednictvím kódu programu. Toto přiřazení lze provést buď v obslužné rutině události DetailsView ItemInserting události, nebo objektu ObjectDataSource Inserting události. Vzhledem k tomu, že jsme se už podívali na použití událostí na úrovni datového ovládacího prvku web, pojďme se tentokrát podívat na události ObjectDataSource.

Krok 4: Přiřazení hodnot k parametrůmCategoryIDSupplierID

V tomto kurzu si představme, že pro naši aplikaci při přidávání nového produktu prostřednictvím tohoto rozhraní by měla být přiřazena CategoryID hodnota a SupplierID hodnota 1. Jak už bylo zmíněno dříve, ObjectDataSource má dvojici událostí před a po úrovni, které se aktivuje během procesu úprav dat. Při vyvolání metody Insert() ObjectDataSource nejprve vyvolá svou Inserting událost, pak zavolá metodu, na kterou Insert() byla jeho metoda namapována, a nakonec vyvolá Inserted událost. Obslužná rutina Inserting události nám poskytuje jednu poslední příležitost k úpravě vstupních parametrů nebo zrušení operace přímo.

Poznámka:

V reálné aplikaci byste pravděpodobně chtěli, aby uživatel zadal kategorii a dodavatele, nebo by tuto hodnotu vybral na základě určitých kritérií nebo obchodní logiky (místo nevidomého výběru ID čísla 1). Bez ohledu na příklad ukazuje, jak programově nastavit hodnotu vstupního parametru z předúrovňové události ObjectDataSource.

Chvíli vytvořte obslužnou rutinu události pro událost ObjectDataSource Inserting . Všimněte si, že druhý vstupní parametr obslužné rutiny události je objekt typu ObjectDataSourceMethodEventArgs, který má vlastnost pro přístup k kolekci parametrů (InputParameters) a vlastnost pro zrušení operace (Cancel).

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

End Sub

V tomto okamžiku InputParameters vlastnost obsahuje ObjectDataSource InsertParameters kolekce s hodnotami přiřazenými z DetailsView. Chcete-li změnit hodnotu jednoho z těchto parametrů, jednoduše použijte: e.InputParameters("paramName") = value. Proto pokud chcete nastavit CategoryID hodnoty 1, SupplierID upravte obslužnou rutinu Inserting události tak, aby vypadala takto:

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

    e.InputParameters("CategoryID") = 1
    e.InputParameters("SupplierID") = 1
End Sub

Tentokrát při přidávání nového produktu (například Acme Soda) CategoryID jsou SupplierID sloupce nového produktu nastaveny na hodnotu 1 (viz obrázek 20).

Nové produkty teď mají hodnoty CategoryID a SupplierID nastavené na 1.

Obrázek 20: Nové produkty teď mají nastavené hodnoty CategoryID a SupplierID hodnoty 1 (kliknutím zobrazíte obrázek v plné velikosti)

Shrnutí

Během úprav, vkládání a odstraňování procesu prochází datový webový ovládací prvek i ObjectDataSource celou řadou událostí na úrovni. V tomto kurzu jsme prozkoumali události na předběžné úrovni a viděli jsme, jak je použít k přizpůsobení vstupních parametrů nebo zrušení operace úpravy dat úplně jak z webového ovládacího prvku dat, tak z událostí ObjectDataSource. V dalším kurzu se podíváme na vytváření a používání obslužných rutin událostí pro události po úrovni.

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí recenzenti tohoto kurzu byli Jackie Goor a Liz Shulok. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.