Wstawianie nowego rekordu w stopce kontrolki GridView (VB)
Chociaż kontrolka GridView nie zapewnia wbudowanej obsługi wstawiania nowego rekordu danych, w tym samouczku pokazano, jak rozszerzyć element GridView w celu uwzględnienia interfejsu wstawiania.
Wprowadzenie
Zgodnie z opisem w samouczku Omówienie wstawiania, aktualizowania i usuwania danych kontrolki GridView, DetailsView i FormView w sieci Web obejmują wbudowane funkcje modyfikacji danych. W przypadku korzystania z deklaratywnych kontrolek źródła danych te trzy kontrolki sieci Web można szybko i łatwo skonfigurować do modyfikowania danych — i w scenariuszach bez konieczności pisania jednego wiersza kodu. Niestety tylko kontrolki DetailsView i FormView zapewniają wbudowane funkcje wstawiania, edytowania i usuwania. Obiekt GridView oferuje tylko obsługę edytowania i usuwania. Jednak przy odrobinie smaru łokcia możemy rozszerzyć element GridView, aby uwzględnić interfejs wstawiania.
Dodając możliwości wstawiania do kontrolki GridView, odpowiadamy za podjęcie decyzji o sposobie dodawania nowych rekordów, tworzeniu interfejsu wstawiania i pisaniu kodu w celu wstawienia nowego rekordu. W tym samouczku przyjrzymy się dodaniu interfejsu wstawiania do wiersza stopki kontrolki GridView (zobacz Rysunek 1). Komórka stopki dla każdej kolumny zawiera odpowiedni element interfejsu użytkownika zbierania danych (Pole tekstowe dla nazwy produktu, Lista rozwijana dla dostawcy itd.). Potrzebujemy również kolumny przycisku Dodaj, który po kliknięciu spowoduje powrót i wstawi nowy rekord do Products
tabeli przy użyciu wartości podanych w wierszu stopki.
Rysunek 1. Wiersz stopki zawiera interfejs dodawania nowych produktów (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 1. Wyświetlanie informacji o produkcie w siatceView
Zanim zaczniemy się martwić o utworzenie interfejsu wstawiania w stopce GridView, najpierw skoncentrujmy się na dodaniu elementu GridView do strony zawierającej listę produktów w bazie danych. Zacznij od otwarcia InsertThroughFooter.aspx
strony w EnhancedGridView
folderze i przeciągnij element GridView z przybornika do Projektant, ustawiając właściwość GridView ID
na Products
. Następnie użyj tagu inteligentnego GridView, aby powiązać go z nowym obiektem ObjectDataSource o nazwie ProductsDataSource
.
Rysunek 2. Utwórz nową nazwę ObjectDataSource o nazwie ProductsDataSource
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Skonfiguruj obiekt ObjectDataSource, aby użyć ProductsBLL
metody s GetProducts()
klasy w celu pobrania informacji o produkcie. Na potrzeby tego samouczka skoncentrujmy się ściśle na dodawaniu funkcji wstawiania i nie martwimy się o edytowanie i usuwanie. W związku z tym upewnij się, że lista rozwijana na karcie INSERT jest ustawiona AddProduct()
na i że listy rozwijane na kartach UPDATE i DELETE są ustawione na wartość (Brak) .
Rysunek 3. Mapowanie metody na metodę AddProduct
ObjectDataSource Insert()
(Kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 4. Ustawianie kart UPDATE i DELETE Drop-Down Listy na (Brak) (Kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy Kreatora konfigurowania źródła danych objectDataSource program Visual Studio automatycznie doda pola do kontrolki GridView dla każdego z odpowiednich pól danych. Na razie pozostaw wszystkie pola dodane przez program Visual Studio. W dalszej części tego samouczka wrócimy i usuniemy niektóre pola, których wartości nie muszą być określone podczas dodawania nowego rekordu.
Ponieważ w bazie danych znajduje się blisko 80 produktów, użytkownik będzie musiał przewijać aż do dołu strony internetowej, aby dodać nowy rekord. W związku z tym włączmy stronicowanie, aby interfejs wstawiania był bardziej widoczny i dostępny. Aby włączyć stronicowanie, zaznacz pole wyboru Włącz stronicowanie z tagu inteligentnego GridView.
Na tym etapie znaczniki deklaratywne gridView i ObjectDataSource powinny wyglądać podobnie do następujących:
<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>
Rysunek 5. Wszystkie pola danych produktu są wyświetlane w stronicowanym widoku GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2. Dodawanie wiersza stopki
Wraz z nagłówkiem i wierszami danych element GridView zawiera wiersz stopki. Wiersze nagłówka i stopki są wyświetlane w zależności od wartości właściwości GridView s ShowHeader
i ShowFooter
. Aby wyświetlić wiersz stopki, po prostu ustaw ShowFooter
właściwość na True
. Jak pokazano na rysunku 6, ustawienie ShowFooter
właściwości w celu True
dodawania wiersza stopki do siatki.
Rysunek 6. Aby wyświetlić wiersz stopki, ustaw ShowFooter
na True
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Należy pamiętać, że wiersz stopki ma ciemnoczerwony kolor tła. Jest to spowodowane utworzonym motywem DataWebControls i zastosowanym do wszystkich stron z powrotem w samouczku Wyświetlanie danych za pomocą obiektuDataSource . W szczególności GridView.skin
plik konfiguruje FooterStyle
właściwość tak, aby korzystała FooterStyle
z klasy CSS. Klasa jest definiowana FooterStyle
w Styles.css
następujący sposób:
.FooterStyle
{
background-color: #a33;
color: White;
text-align: right;
}
Uwaga
Zapoznaliśmy się z użyciem wiersza stopki GridView w poprzednich samouczkach. W razie potrzeby zapoznaj się z samouczkiem Wyświetlanie informacji o podsumowaniu w stopce elementu GridView , aby zapoznać się z odświeżaniem.
Po ustawieniu ShowFooter
właściwości na True
, poświęć chwilę, aby wyświetlić dane wyjściowe w przeglądarce. Obecnie wiersz stopki nie zawiera żadnych kontrolek tekstowych ani internetowych. W kroku 3 zmodyfikujemy stopkę dla każdego pola GridView, tak aby zawierała odpowiedni interfejs wstawiania.
Rysunek 7. Pusty wiersz stopki jest wyświetlany nad kontrolkami interfejsu stronicowania (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 3. Dostosowywanie wiersza stopki
W samouczku Using TemplateFields (Używanie pól szablonów w kontrolce GridView ) pokazano, jak znacznie dostosować wyświetlanie określonej kolumny GridView przy użyciu pól TemplateFields (w przeciwieństwie do elementów BoundFields lub CheckBoxFields); w dostosowywaniu interfejsu modyfikacji danych przyjrzeliśmy się użyciu pola szablonów w celu dostosowania interfejsu edycji w elemecie GridView. Pamiętaj, że pole szablonu składa się z wielu szablonów, które definiują kombinację znaczników, kontrolek sieci Web i składni powiązania danych używanych dla niektórych typów wierszy. Element ItemTemplate
, na przykład określa szablon używany dla wierszy tylko do odczytu, podczas gdy EditItemTemplate
definiuje szablon dla edytowalnego wiersza.
Wraz z elementami ItemTemplate
i EditItemTemplate
pole TemplateField zawiera FooterTemplate
również element określający zawartość wiersza stopki. W związku z tym możemy dodać kontrolki sieci Web potrzebne dla każdego wstawiania interfejsu pola do elementu FooterTemplate
. Aby rozpocząć, przekonwertuj wszystkie pola w elemecie GridView na TemplateFields. Można to zrobić, klikając link Edytuj kolumny w tagu inteligentnym GridView, wybierając każde pole w lewym dolnym rogu, a następnie klikając link Konwertuj to pole na pole szablonu.
Rysunek 8. Konwertowanie każdego pola na pole szablonu
Kliknięcie pola Konwertuj to pole na pole szablonu powoduje przekształcenie bieżącego typu pola w równoważne pole szablonu. Na przykład każde pole BoundField jest zastępowane przez element TemplateField z elementem ItemTemplate
zawierającym etykietę, która wyświetla odpowiednie pole danych i EditItemTemplate
wyświetla pole danych w polu TextBox. Pole ProductName
powiązane zostało przekonwertowane na następujące znaczniki 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>
Podobnie pole Discontinued
CheckBoxField zostało przekonwertowane na pole szablonu, którego ItemTemplate
i EditItemTemplate
zawiera kontrolkę sieci Web CheckBox (z wyłączoną ItemTemplate
kontrolką CheckBox). Pole powiązane tylko do ProductID
odczytu zostało przekonwertowane na pole szablonu z kontrolką Etykieta zarówno w elemecie , jak ItemTemplate
i EditItemTemplate
. Krótko mówiąc, konwertowanie istniejącego pola GridView na pole TemplateField jest szybkim i łatwym sposobem przełączania się do bardziej dostosowywanego pola TemplateField bez utraty żadnej z istniejących funkcji pola.
Ponieważ funkcja GridView, z którymi pracujemy, nie obsługuje edycji, możesz usunąć element EditItemTemplate
z każdego pola szablonu ItemTemplate
, pozostawiając tylko element . Po wykonaniu tej czynności znacznik deklaratywnej kontrolki GridView powinien wyglądać następująco:
<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>
Teraz, gdy każde pole GridView zostało przekonwertowane na pole szablonu, możemy wprowadzić odpowiedni interfejs wstawiania do każdego pola s FooterTemplate
. Niektóre pola nie będą miały interfejsu wstawiania (ProductID
na przykład); inne będą się różnić w kontrolkach sieci Web używanych do zbierania nowych informacji o produkcie.
Aby utworzyć interfejs edycji, wybierz link Edytuj szablony z tagu inteligentnego GridView. Następnie z listy rozwijanej wybierz odpowiednie pole s FooterTemplate
i przeciągnij odpowiednią kontrolkę z przybornika na Projektant.
Rysunek 9. Dodawanie odpowiedniego interfejsu wstawiania do poszczególnych pól FooterTemplate
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Poniższa lista punktowana wylicza pola GridView, określając interfejs wstawiania do dodania:
ProductID
Brak.ProductName
dodaj pole TextBox i ustaw jegoID
wartość naNewProductName
. Dodaj kontrolkę RequiredFieldValidator, aby upewnić się, że użytkownik wprowadza wartość nazwy nowego produktu.SupplierID
Brak.CategoryID
Brak.QuantityPerUnit
dodaj pole TextBox, ustawiając jegoID
wartość naNewQuantityPerUnit
.UnitPrice
dodaj pole TextBox o nazwieNewUnitPrice
i element CompareValidator, który gwarantuje, że wprowadzona wartość jest wartością waluty większą lub równą zero.UnitsInStock
użyj pola TextBox, któregoID
ustawiono wartośćNewUnitsInStock
. Dołącz moduł CompareValidator, który gwarantuje, że wprowadzona wartość jest wartością całkowitą większą lub równą zero.UnitsOnOrder
użyj pola TextBox, któregoID
ustawiono wartośćNewUnitsOnOrder
. Dołącz moduł CompareValidator, który gwarantuje, że wprowadzona wartość jest wartością całkowitą większą lub równą zero.ReorderLevel
użyj pola TextBox, któregoID
ustawiono wartośćNewReorderLevel
. Dołącz moduł CompareValidator, który gwarantuje, że wprowadzona wartość jest wartością całkowitą większą lub równą zero.Discontinued
dodaj pole wyboru, ustawiając wartośćID
NewDiscontinued
na .CategoryName
dodaj listę DropDownList i ustaw jąID
naNewCategoryID
. Powiąż ją z nową usługą ObjectDataSource o nazwieCategoriesDataSource
i skonfiguruj ją tak, aby korzystałaCategoriesBLL
z metody klasy sGetCategories()
. Czy lista DropDownList sListItem
wyświetlaCategoryName
pole danych przy użyciuCategoryID
pola danych jako ich wartości.SupplierName
dodaj listę DropDownList i ustaw jąID
naNewSupplierID
. Powiąż ją z nową usługą ObjectDataSource o nazwieSuppliersDataSource
i skonfiguruj ją tak, aby korzystałaSuppliersBLL
z metody klasy sGetSuppliers()
. Czy lista DropDownList sListItem
wyświetlaCompanyName
pole danych przy użyciuSupplierID
pola danych jako ich wartości.
Dla każdej kontrolki walidacji usuń ForeColor
zaznaczenie właściwości, tak aby FooterStyle
biały kolor pierwszego planu klasy CSS był używany zamiast domyślnego czerwonego koloru. Użyj również właściwości w ErrorMessage
celu uzyskania szczegółowego opisu, ale ustaw Text
właściwość na gwiazdkę. Aby zapobiec spowodowaniu zawijania interfejsu wstawiania do dwóch wierszy kontrolki walidacji, ustaw FooterStyle
właściwość s Wrap
na wartość false dla każdego z FooterTemplate
elementów, które używają kontrolki walidacji. Na koniec dodaj kontrolkę ValidationSummary pod kontrolką GridView i ustaw jej ShowMessageBox
właściwość na True
i jej ShowSummary
właściwość na False
.
Podczas dodawania nowego produktu musimy podać element CategoryID
i SupplierID
. Te informacje są przechwytywane za pośrednictwem list rozwijanych w komórkach stopki dla CategoryName
pól i SupplierName
. Zdecydowałem się używać tych pól w przeciwieństwie do CategoryID
pól i SupplierID
TemplateFields, ponieważ w wierszach danych siatki użytkownik prawdopodobnie bardziej interesuje się wyświetlaniem kategorii i nazw dostawców, a nie ich wartości identyfikatorów. CategoryID
Ponieważ wartości i SupplierID
są teraz przechwytywane w CategoryName
interfejsach wstawiania pól iSupplierName
, możemy usunąć CategoryID
pola i z SupplierID
kontrolki GridView.
Podobnie ProductID
element nie jest używany podczas dodawania nowego produktu, więc pole szablonu ProductID
można również usunąć. Pozostawmy ProductID
jednak pole w siatce. Oprócz kontrolek TextBoxes, DropDownLists, CheckBoxes i validation tworzących interfejs wstawiania będziemy również potrzebować przycisku Dodaj, który po kliknięciu wykonuje logikę dodawania do bazy danych. W kroku 4 dołączymy przycisk Dodaj w interfejsie wstawiania w elemecie ProductID
TemplateField s FooterTemplate
.
Możesz poprawić wygląd różnych pól GridView. Na przykład możesz sformatować UnitPrice
wartości jako walutę, wyrównać prawym przyciskiem UnitsInStock
do pól , UnitsOnOrder
i ReorderLevel
oraz zaktualizować HeaderText
wartości pola TemplateFields.
Po utworzeniu mnóstwa interfejsów wstawiania w FooterTemplate
s, usunięciu SupplierID
pól i CategoryID
szablonów oraz poprawie estetyki siatki za pomocą formatowania i wyrównania pól TemplateFields deklaratywny znacznik GridView powinien wyglądać podobnie do następującego:
<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>
Po wyświetleniu w przeglądarce wiersz stopki GridView zawiera teraz ukończony interfejs wstawiania (zobacz Rysunek 10). W tym momencie interfejs wstawiania nie zawiera środków dla użytkownika, aby wskazać, że wprowadziła dane dla nowego produktu i chce wstawić nowy rekord do bazy danych. Ponadto musimy jeszcze rozwiązać sposób, w jaki dane wprowadzone w stopce przełożą się na nowy rekord w Products
bazie danych. W kroku 4 przyjrzymy się, jak dołączyć przycisk Dodaj do interfejsu wstawiania i jak wykonać kod po kliknięciu. Krok 5 pokazuje, jak wstawić nowy rekord przy użyciu danych z stopki.
Rysunek 10. Stopka GridView udostępnia interfejs dodawania nowego rekordu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 4. Dołączenie przycisku Dodaj w interfejsie wstawiania
Musimy dołączyć przycisk Dodaj gdzieś w interfejsie wstawiania, ponieważ interfejs wstawiania wierszy stopki obecnie nie ma środków dla użytkownika, aby wskazać, że zostały one ukończone, wprowadzając nowe informacje o produkcie. Można to umieścić w jednym z istniejących FooterTemplate
elementów lub dodać nową kolumnę do siatki w tym celu. W tym samouczku umieśćmy przycisk Dodaj w elemecie ProductID
TemplateField s FooterTemplate
.
W Projektant kliknij link Edytuj szablony w tagu inteligentnym GridView, a następnie wybierz ProductID
pole z FooterTemplate
listy rozwijanej. Dodaj kontrolkę Sieci Web przycisku (lub LinkButton lub ImageButton, jeśli wolisz) do szablonu, ustawiając jego identyfikator na AddProduct
, CommandName
na Wstaw, a jej Text
właściwość na Dodaj, jak pokazano na rysunku 11.
Rysunek 11. Umieść przycisk Dodaj w polach ProductID
szablonów FooterTemplate
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Po dołączeniu przycisku Dodaj przetestuj stronę w przeglądarce. Należy pamiętać, że po kliknięciu przycisku Dodaj z nieprawidłowymi danymi w interfejsie wstawiania następuje zwarcie zwrotne, a kontrolka ValidationSummary wskazuje nieprawidłowe dane (patrz Rysunek 12). Po wprowadzeniu odpowiednich danych kliknięcie przycisku Dodaj powoduje powrót. Żaden rekord nie jest jednak dodawany do bazy danych. Musimy napisać trochę kodu, aby rzeczywiście wykonać wstawianie.
Rysunek 12. Powrót po awarii przycisku dodaj jest zwarty, jeśli w interfejsie wstawiania znajdują się nieprawidłowe dane (kliknij, aby wyświetlić obraz pełnowymiarowy)
Uwaga
Kontrolki walidacji w interfejsie wstawiania nie zostały przypisane do grupy walidacji. Działa to prawidłowo, tak długo, jak interfejs wstawiania jest jedynym zestawem kontrolek walidacji na stronie. Jeśli jednak na stronie znajdują się inne kontrolki weryfikacji (takie jak kontrolki walidacji w interfejsie edycji siatki), kontrolki walidacji w interfejsie wstawiania i Dodaj właściwości przycisku ValidationGroup
powinny mieć przypisaną tę samą wartość, aby skojarzyć te kontrolki z określoną grupą walidacji. Aby uzyskać więcej informacji na temat partycjonowania kontrolek walidacji na stronie w grupach weryfikacji, zobacz Dissecting the Validation Controls in ASP.NET 2.0 (Rozłączanie kontrolek weryfikacji w ASP.NET 2.0 ).
Krok 5. Wstawianie nowego rekorduProducts
do tabeli
W przypadku korzystania z wbudowanych funkcji edycji elementu GridView funkcja GridView automatycznie obsługuje całą pracę niezbędną do przeprowadzenia aktualizacji. W szczególności po kliknięciu przycisku Aktualizuj kopiuje wartości wprowadzone z interfejsu edycji do parametrów w kolekcji ObjectDataSource i uruchamia aktualizację, wywołując metodę ObjectDataSourceUpdateParameters
.Update()
Ponieważ funkcja GridView nie udostępnia takich wbudowanych funkcji wstawiania, musimy zaimplementować kod, który wywołuje metodę ObjectDataSource i Insert()
kopiuje wartości z interfejsu wstawiania do kolekcji ObjectDataSource InsertParameters
.
Ta logika wstawiania powinna zostać wykonana po kliknięciu przycisku Dodaj. Zgodnie z opisem w samouczku Dodawanie i odpowiadanie na przyciski w elemecie GridView, w dowolnym momencie kliknięcie przycisku, elementu LinkButton lub elementu ImageButton w siatceview, zdarzenie GridView RowCommand
zostanie wyzwolone po powrocie zwrotne. To zdarzenie jest wyzwalane, czy przycisk Button, LinkButton lub ImageButton został dodany jawnie, na przykład przycisk Dodaj w wierszu stopki lub jeśli został automatycznie dodany przez kontrolkę GridView (na przykład LinkButtons w górnej części każdej kolumny po wybraniu opcji Włącz sortowanie, lub LinkButtons w interfejsie stronicowania po wybraniu opcji Włącz stronicowanie).
W związku z tym, aby odpowiedzieć użytkownikowi klikając przycisk Dodaj, musimy utworzyć procedurę obsługi zdarzeń dla zdarzenia GridView.RowCommand
Ponieważ to zdarzenie jest uruchamiane za każdym razem, gdy zostanie kliknięty dowolny przycisk Button, LinkButton lub ImageButton w elemecie GridView, ważne jest, aby kontynuować tylko logikę wstawiania, jeśli CommandName
właściwość przekazana do programu obsługi zdarzeń jest mapowana na CommandName
wartość przycisku Dodaj ( Wstaw). Ponadto należy również kontynuować tylko wtedy, gdy kontrole weryfikacji zgłaszają prawidłowe dane. Aby to uwzględnić, utwórz procedurę obsługi zdarzeń dla RowCommand
zdarzenia przy użyciu następującego kodu:
Protected Sub Products_RowCommand(sender As Object, e As GridViewCommandEventArgs) _
Handles Products.RowCommand
' Insert data if the CommandName == "Insert"
' and the validation controls indicate valid data...
If e.CommandName = "Insert" AndAlso Page.IsValid Then
' TODO: Insert new record...
End If
End Sub
Uwaga
Być może zastanawiasz się, dlaczego program obsługi zdarzeń przeszkadza sprawdzanie Page.IsValid
właściwości. Po tym wszystkim nie będzie pomijany po powrocie zwrotnym, jeśli w interfejsie wstawiania podano nieprawidłowe dane? To założenie jest poprawne, o ile użytkownik nie wyłączył języka JavaScript lub podjął kroki w celu obejścia logiki weryfikacji po stronie klienta. Krótko mówiąc, nigdy nie należy polegać ściśle na weryfikacji po stronie klienta; przed rozpoczęciem pracy z danymi należy zawsze wykonać sprawdzanie poprawności po stronie serwera.
W kroku 1 utworzyliśmy obiekt ObjectDataSource, ProductsDataSource
tak aby jego Insert()
metoda została zamapowana na metodę ProductsBLL
s AddProduct
klasy. Aby wstawić nowy rekord do Products
tabeli, możemy po prostu wywołać metodę ObjectDataSource Insert()
:
Protected Sub Products_RowCommand(sender As Object, e As GridViewCommandEventArgs) _
Handles Products.RowCommand
' Insert data if the CommandName == "Insert"
' and the validation controls indicate valid data...
If e.CommandName = "Insert" AndAlso Page.IsValid Then
' Insert new record
ProductsDataSource.Insert()
End If
End Sub
Insert()
Po wywołaniu metody wszystkie pozostałe elementy to skopiowanie wartości z interfejsu wstawiania do parametrów przekazanych do ProductsBLL
metody klasy.AddProduct
Jak widzieliśmy już w samouczku Badanie zdarzeń skojarzonych z wstawianiem, aktualizowaniem i usuwaniem , można to zrobić za pośrednictwem zdarzenia ObjectDataSource Inserting
. Inserting
W przypadku, gdy musimy programowo odwołać się do kontrolek z Products
wiersza stopki GridView i przypisać ich wartości do e.InputParameters
kolekcji. Jeśli użytkownik pomija wartość, taką jak pozostawienie pola Tekstowego pustego ReorderLevel
, musimy określić, że wartość wstawiona do bazy danych powinna mieć wartość NULL
. AddProducts
Ponieważ metoda akceptuje typy dopuszczane wartości null dla pól bazy danych z możliwością wartości null, wystarczy użyć typu dopuszczalnego wartości null i ustawić jej wartość na Nothing
w przypadku, gdy dane wejściowe użytkownika są pomijane.
Protected Sub ProductsDataSource_Inserting _
(sender As Object, e As .ObjectDataSourceMethodEventArgs) _
Handles ProductsDataSource.Inserting
' Programmatically reference Web controls in the inserting interface...
Dim NewProductName As TextBox = _
Products.FooterRow.FindControl("NewProductName")
Dim NewCategoryID As DropDownList = _
Products.FooterRow.FindControl("NewCategoryID")
Dim NewSupplierID As DropDownList = _
Products.FooterRow.FindControl("NewSupplierID")
Dim NewQuantityPerUnit As TextBox = _
Products.FooterRow.FindControl("NewQuantityPerUnit")
Dim NewUnitPrice As TextBox = _
Products.FooterRow.FindControl("NewUnitPrice")
Dim NewUnitsInStock As TextBox = _
Products.FooterRow.FindControl("NewUnitsInStock")
Dim NewUnitsOnOrder As TextBox = _
Products.FooterRow.FindControl("NewUnitsOnOrder")
Dim NewReorderLevel As TextBox = _
Products.FooterRow.FindControl("NewReorderLevel")
Dim NewDiscontinued As CheckBox = _
Products.FooterRow.FindControl("NewDiscontinued")
' Set the ObjectDataSource's InsertParameters values...
e.InputParameters("productName") = NewProductName.Text
e.InputParameters("supplierID") = _
Convert.ToInt32(NewSupplierID.SelectedValue)
e.InputParameters("categoryID") = _
Convert.ToInt32(NewCategoryID.SelectedValue)
Dim quantityPerUnit As String = Nothing
If Not String.IsNullOrEmpty(NewQuantityPerUnit.Text) Then
quantityPerUnit = NewQuantityPerUnit.Text
End If
e.InputParameters("quantityPerUnit") = quantityPerUnit
Dim unitPrice As Nullable(Of Decimal) = Nothing
If Not String.IsNullOrEmpty(NewUnitPrice.Text) Then
unitPrice = Convert.ToDecimal(NewUnitPrice.Text)
End If
e.InputParameters("unitPrice") = unitPrice
Dim unitsInStock As Nullable(Of Short) = Nothing
If Not String.IsNullOrEmpty(NewUnitsInStock.Text) Then
unitsInStock = Convert.ToInt16(NewUnitsInStock.Text)
End If
e.InputParameters("unitsInStock") = unitsInStock
Dim unitsOnOrder As Nullable(Of Short) = Nothing
If Not String.IsNullOrEmpty(NewUnitsOnOrder.Text) Then
unitsOnOrder = Convert.ToInt16(NewUnitsOnOrder.Text)
End If
e.InputParameters("unitsOnOrder") = unitsOnOrder
Dim reorderLevel As Nullable(Of Short) = Nothing
If Not String.IsNullOrEmpty(NewReorderLevel.Text) Then
reorderLevel = Convert.ToInt16(NewReorderLevel.Text)
End If
e.InputParameters("reorderLevel") = reorderLevel
e.InputParameters("discontinued") = NewDiscontinued.Checked
End Sub
Po zakończeniu Inserting
obsługi zdarzeń nowe rekordy można dodać do Products
tabeli bazy danych za pośrednictwem wiersza stopki GridView. Przejdź do przodu i spróbuj dodać kilka nowych produktów.
Ulepszanie i dostosowywanie operacji dodawania
Obecnie kliknięcie przycisku Dodaj powoduje dodanie nowego rekordu do tabeli bazy danych, ale nie udostępnia żadnej wizualnej opinii, że rekord został pomyślnie dodany. W idealnym przypadku kontrolka sieci Web etykiety lub pole alertu po stronie klienta informuje użytkownika o pomyślnym zakończeniu wstawiania. Zostawię to jako ćwiczenie dla czytelnika.
Element GridView używany w tym samouczku nie stosuje żadnej kolejności sortowania do wymienionych produktów ani nie zezwala użytkownikowi końcowemu na sortowanie danych. W związku z tym rekordy są uporządkowane tak, jak znajdują się w bazie danych według ich pola klucza podstawowego. Ponieważ każdy nowy rekord ma ProductID
wartość większą niż ostatni, za każdym razem, gdy dodawany jest nowy produkt, jest on naklejany na końcu siatki. W związku z tym możesz automatycznie wysłać użytkownika do ostatniej strony elementu GridView po dodaniu nowego rekordu. Można to zrobić, dodając następujący wiersz kodu po wywołaniu metody ProductsDataSource.Insert()
w RowCommand
programie obsługi zdarzeń, aby wskazać, że użytkownik musi zostać wysłany na ostatnią stronę po powiązaniu danych z kontrolką GridView:
' Indicate that the user needs to be sent to the last page
SendUserToLastPage = True
SendUserToLastPage
to zmienna logiczna na poziomie strony, która początkowo ma przypisaną wartość .False
W procedurze obsługi zdarzeń usługi GridView DataBound
, jeśli SendUserToLastPage
jest to fałsz, właściwość zostanie zaktualizowana, PageIndex
aby wysłać użytkownika do ostatniej strony.
Protected Sub Products_DataBound(sender As Object, e As EventArgs) _
Handles Products.DataBound
' Send user to last page of data, if needed
If SendUserToLastPage Then
Products.PageIndex = Products.PageCount - 1
End If
End Sub
Powodem, PageIndex
dla którego właściwość jest ustawiona w DataBound
procedurze obsługi zdarzeń (w przeciwieństwie do RowCommand
programu obsługi zdarzeń), jest to, że gdy RowCommand
program obsługi zdarzeń uruchomi jeszcze nowy rekord do Products
tabeli bazy danych. W związku z tym w procedurze obsługi zdarzeń RowCommand
ostatni indeks strony (PageCount - 1
) reprezentuje ostatni indeks strony przed dodaniu nowego produktu. W przypadku większości dodanych produktów ostatni indeks strony jest taki sam po dodaniu nowego produktu. Jednak gdy dodany produkt spowoduje wyświetlenie nowego indeksu ostatniej strony, jeśli niepoprawnie zaktualizujemy PageIndex
element w RowCommand
procedurze obsługi zdarzeń, nastąpi przekierowanie do drugiej do ostatniej strony (ostatni indeks strony przed dodaniem nowego produktu) w przeciwieństwie do nowego indeksu ostatniej strony. DataBound
Ponieważ program obsługi zdarzeń jest uruchamiany po dodaniu nowego produktu i odbiciu danych do siatki, ustawiając PageIndex
tam właściwość, wiemy, że otrzymujemy prawidłowy indeks ostatniej strony.
Na koniec element GridView używany w tym samouczku jest dość szeroki ze względu na liczbę pól, które należy zebrać w celu dodania nowego produktu. Ze względu na tę szerokość preferowany może być układ pionowy elementu DetailsView. Ogólną szerokość kontrolki GridView można zmniejszyć, zbierając mniej danych wejściowych. Być może nie musimy zbierać UnitsOnOrder
pól , UnitsInStock
i ReorderLevel
podczas dodawania nowego produktu, w tym przypadku te pola można usunąć z widoku GridView.
Aby dostosować zebrane dane, możemy użyć jednego z dwóch metod:
- Kontynuuj korzystanie z
AddProduct
metody, która oczekuje wartości dlaUnitsOnOrder
pól ,UnitsInStock
iReorderLevel
. W procedurzeInserting
obsługi zdarzeń podaj trwale zakodowane wartości domyślne do użycia dla tych danych wejściowych, które zostały usunięte z interfejsu wstawiania. - Utwórz nowe przeciążenie
AddProduct
metody wProductsBLL
klasie, która nie akceptuje danych wejściowych dlaUnitsOnOrder
pól ,UnitsInStock
iReorderLevel
. Następnie na stronie ASP.NET skonfiguruj obiekt ObjectDataSource do używania tego nowego przeciążenia.
Każda z opcji będzie działać równie dobrze. W poprzednich samouczkach użyliśmy tej drugiej opcji, tworząc wiele przeciążeń dla ProductsBLL
metody klasy UpdateProduct
.
Podsumowanie
Kontrolka GridView nie ma wbudowanych funkcji wstawiania znalezionych w kontrolkach DetailsView i FormView, ale przy odrobinie wysiłku można dodać interfejs wstawiania do wiersza stopki. Aby wyświetlić wiersz stopki w obiekcie GridView, po prostu ustaw jego ShowFooter
właściwość na True
wartość . Zawartość wiersza stopki można dostosować dla każdego pola, konwertując pole na wartość TemplateField i dodając interfejs wstawiania do obiektu FooterTemplate
. Jak pokazano w tym samouczku, FooterTemplate
element może zawierać kontrolki Buttons, TextBoxes, DropDownLists, CheckBoxes, źródła danych służące do wypełniania kontrolek sieci Web opartych na danych (takich jak DropDownLists) i kontrolek weryfikacji. Oprócz kontrolek do zbierania danych wejściowych użytkownika potrzebny jest przycisk dodawania, przycisk LinkButton lub imageButton.
Po kliknięciu przycisku Dodaj wywoływana Insert()
jest metoda ObjectDataSource, aby rozpocząć wstawianie przepływu pracy. Następnie obiekt ObjectDataSource wywoła skonfigurowaną metodę insert ( ProductsBLL
metodę klasy s AddProduct
w tym samouczku). Przed wywołaniem metody inserting należy skopiować wartości z interfejsu wstawiania kontrolki GridView do kolekcji ObjectDataSource InsertParameters
. Można to osiągnąć przez programowe odwoływanie się do wstawiania kontrolek sieci Web interfejsu w procedurze obsługi zdarzeń obiektu Inserting
ObjectDataSource.
W tym samouczku przedstawiono techniki ulepszania wyglądu obiektu GridView. W następnym zestawie samouczków dowiesz się, jak pracować z danymi binarnymi, takimi jak obrazy, pliki PDF, Word dokumenty itd., oraz kontrolki sieci Web danych.
Szczęśliwe programowanie!
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka był Bernadette Leigh. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .