Вставка новой записи из нижнего колонтитула GridView (VB)
Хотя элемент управления GridView не обеспечивает встроенную поддержку вставки новой записи данных, в этом руководстве показано, как расширить GridView, чтобы включить интерфейс вставки.
Введение
Как описано в руководстве Общие сведения о вставке, обновлении и удалении данных , элементы управления GridView, DetailsView и FormView Web включают встроенные возможности изменения данных. При использовании с декларативными элементами управления источником данных эти три веб-элемента управления можно быстро и легко настроить для изменения данных и в сценариях без написания одной строки кода. К сожалению, только элементы управления DetailsView и FormView предоставляют встроенные возможности вставки, редактирования и удаления. GridView поддерживает только редактирование и удаление. Однако с небольшим количеством смазок локоть можно дополнить GridView, чтобы включить интерфейс вставки.
При добавлении возможностей вставки в GridView мы отвечаем за принятие решения о том, как будут добавляться новые записи, создавать интерфейс вставки и писать код для вставки новой записи. В этом руководстве мы рассмотрим добавление интерфейса вставки в строку нижнего колонтитула GridView (см. рис. 1). Ячейка нижнего колонтитула для каждого столбца содержит соответствующий элемент пользовательского интерфейса сбора данных (TextBox для названия продукта, DropDownList для поставщика и т. д.). Нам также нужен столбец для кнопки Добавить, который при нажатии будет вызывать обратную передачу и вставлять новую запись в таблицу Products
, используя значения, указанные в строке нижнего колонтитула.
Рис. 1. Строка нижнего колонтитула предоставляет интерфейс для добавления новых продуктов (щелкните для просмотра полноразмерного изображения)
Шаг 1. Отображение сведений о продукте в GridView
Прежде чем приступить к созданию интерфейса вставки в нижнем колонтитуле GridView, давайте сначала сосредоточимся на добавлении GridView на страницу со списком продуктов в базе данных. Начните с открытия InsertThroughFooter.aspx
страницы в папке EnhancedGridView
и перетащите GridView из панели элементов на Designer, задав свойству GridView ID
значение Products
. Затем используйте смарт-тег GridView, чтобы привязать его к новому объекту ObjectDataSource с именем ProductsDataSource
.
Рис. 2. Создание объекта ObjectDataSource с именем ProductsDataSource
(щелкните для просмотра полноразмерного изображения)
Настройте ObjectDataSource для использования ProductsBLL
метода класса для GetProducts()
получения сведений о продукте. В этом руководстве мы сосредоточимся исключительно на добавлении возможностей вставки и не будем беспокоиться о редактировании и удалении. Поэтому убедитесь, что для раскрывающегося списка на вкладке ВСТАВКА задано значение AddProduct()
, а для раскрывающихся списков на вкладках UPDATE и DELETE задано значение (Нет).
Рис. 3. Сопоставление AddProduct
метода с методом ObjectDataSource Insert()
(щелкните для просмотра полноразмерного изображения)
Рис. 4. Задайте для Drop-Down Списки вкладок UPDATE и DELETE значение (Нет) (щелкните для просмотра полноразмерного изображения)
После завершения работы мастера настройки источника данных ObjectDataSource Visual Studio автоматически добавит поля в GridView для каждого из соответствующих полей данных. Пока оставьте все поля, добавленные Visual Studio. Далее в этом руководстве мы вернемся и удалим некоторые поля, значения которых не нужно указывать при добавлении новой записи.
Так как в базе данных около 80 продуктов, пользователю придется прокрутить весь путь вниз до нижней части веб-страницы, чтобы добавить новую запись. Поэтому разрешите разбиение по страницам, чтобы сделать интерфейс вставки более видимым и доступным. Чтобы включить разбиение по страницам, просто проверка флажок Включить разбиение по страницам из смарт-тега GridView.
На этом этапе декларативная разметка GridView и ObjectDataSource должна выглядеть примерно так:
<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>
Рис. 5. Все поля данных о продукте отображаются в представлении GridView с постраничной диаграммой (щелкните для просмотра полноразмерного изображения)
Шаг 2. Добавление строки нижнего колонтитула
Вместе со строками заголовков и данных GridView включает строку нижнего колонтитула. Строки колонтитулов отображаются в зависимости от значений свойств GridView ShowHeader
и ShowFooter
. Чтобы отобразить строку нижнего колонтитула, просто присвойте свойству ShowFooter
значение True
. Как показано на рисунке 6, для свойства ShowFooter
добавляется True
строка нижнего колонтитула в сетку.
Рис. 6. Чтобы отобразить строку нижнего колонтитула, установите значение ShowFooter
True
(Щелкните для просмотра полноразмерного изображения)
Обратите внимание, что строка нижнего колонтитула имеет темно-красный цвет фона. Это связано с темой DataWebControls, которую мы создали и применили ко всем страницам еще в учебнике Отображение данных с помощью ObjectDataSource . В частности, GridView.skin
файл настраивает FooterStyle
свойство таким образом, что использует FooterStyle
класс CSS. Класс FooterStyle
определяется в Styles.css
следующим образом:
.FooterStyle
{
background-color: #a33;
color: White;
text-align: right;
}
Примечание
Мы изучили использование строки нижнего колонтитула GridView в предыдущих руководствах. При необходимости вернитесь к разделу Отображение сводной информации в учебнике По нижнему колонтитулов GridView , чтобы получить дополнительные сведения.
Задав ShowFooter
для свойства значение True
, просмотрите выходные данные в браузере. В настоящее время строка нижнего колонтитула не содержит ни текста, ни веб-элементов управления. На шаге 3 мы изменим нижний колонтитул для каждого поля GridView, чтобы он был включен в соответствующий интерфейс вставки.
Рис. 7. Строка пустого нижнего колонтитула отображается над элементами управления интерфейсом подкачки (щелкните для просмотра полноразмерного изображения)
Шаг 3. Настройка строки нижнего колонтитула
В руководстве По использованию templateFields в элементе управления GridView мы узнали, как настроить отображение определенного столбца GridView с помощью TemplateFields (в отличие от BoundFields или CheckBoxFields); В разделе Настройка интерфейса изменения данных мы рассмотрели использование TemplateFields для настройки интерфейса редактирования в GridView. Помните, что TemplateField состоит из нескольких шаблонов, которые определяют сочетание разметки, веб-элементов управления и синтаксиса привязки данных, используемого для определенных типов строк. , ItemTemplate
например, задает шаблон, используемый для строк, доступных только для чтения, а EditItemTemplate
определяет шаблон для редактируемой строки.
Наряду с ItemTemplate
и EditItemTemplate
templateField также содержит FooterTemplate
объект , указывающий содержимое строки нижнего колонтитула. Таким образом, мы можем добавить веб-элементы управления, необходимые для каждого интерфейса вставки полей, в FooterTemplate
. Для начала преобразуйте все поля в GridView в TemplateFields. Это можно сделать, щелкнув ссылку Изменить столбцы в смарт-теге GridView, выбрав каждое поле в левом нижнем углу и щелкнув ссылку Преобразовать это поле в TemplateField.
Рис. 8. Преобразование каждого поля в TemplateField
Если щелкнуть Преобразовать это поле в TemplateField, текущий тип поля преобразуется в эквивалент TemplateField. Например, каждый BoundField заменяется шаблоном TemplateField с ItemTemplate
элементом , который содержит метку, отображающую соответствующее поле данных, и EditItemTemplate
, отображающую поле данных в Элементе TextBox. BoundField ProductName
был преобразован в следующую разметку 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>
Аналогичным образом CheckBoxField был преобразован в TemplateField, Discontinued
в котором ItemTemplate
и EditItemTemplate
содержат веб-элемент управления CheckBox (с отключенным элементом ItemTemplate
CheckBox). BoundField, доступный только для ProductID
чтения, был преобразован в TemplateField с элементом управления Label в и ItemTemplate
EditItemTemplate
. Короче говоря, преобразование существующего поля GridView в TemplateField — это быстрый и простой способ переключиться на более настраиваемый TemplateField без потери существующих функциональных возможностей поля.
Так как GridView, с которым мы работаем, не поддерживает редактирование EditItemTemplate
, вы можете удалить из каждого TemplateField, оставив только ItemTemplate
. После этого декларативная разметка GridView должна выглядеть следующим образом:
<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>
Теперь, когда каждое поле GridView было преобразовано в TemplateField, можно ввести соответствующий интерфейс вставки в каждое поле .FooterTemplate
В некоторых полях не будет интерфейса вставки (ProductID
например; другие будут отличаться в веб-элементах управления, используемых для сбора сведений о новом продукте).
Чтобы создать интерфейс редактирования, щелкните ссылку Изменить шаблоны в смарт-теге GridView. Затем в раскрывающемся списке выберите соответствующие поля FooterTemplate
и перетащите соответствующий элемент управления из панели элементов в Designer.
Рис. 9. Добавление соответствующего интерфейса вставки в каждое поле FooterTemplate
(щелкните для просмотра полноразмерного изображения)
Следующий маркированный список перечисляет поля GridView, указывая добавляемый интерфейс вставки:
ProductID
Ни один.ProductName
Добавьте элемент TextBox и задайте для нееID
значениеNewProductName
. Добавьте также элемент управления RequiredFieldValidator, чтобы убедиться, что пользователь вводит значение для имени нового продукта.SupplierID
Ни один.CategoryID
Ни один.QuantityPerUnit
добавьте элемент TextBox, задав для нееID
значениеNewQuantityPerUnit
.UnitPrice
добавьте элемент TextBox с именемNewUnitPrice
и CompareValidator, который гарантирует, что введенное значение является денежным значением, превышающим или равным нулю.UnitsInStock
используйте элемент TextBox, для которогоID
задано значениеNewUnitsInStock
. Включите CompareValidator, который гарантирует, что введенное значение является целочисленным значением, превышающим или равным нулю.UnitsOnOrder
используйте элемент TextBox, для которогоID
задано значениеNewUnitsOnOrder
. Включите CompareValidator, который гарантирует, что введенное значение является целочисленным значением, превышающим или равным нулю.ReorderLevel
используйте элемент TextBox, для которогоID
задано значениеNewReorderLevel
. Включите CompareValidator, который гарантирует, что введенное значение является целочисленным значением, превышающим или равным нулю.Discontinued
добавьте элемент CheckBox, задав для нееID
значениеNewDiscontinued
.CategoryName
Добавьте DropDownList и задайте для нееID
значениеNewCategoryID
. Привяжите его к новому объекту ObjectDataSource с именемCategoriesDataSource
и настройте для использованияCategoriesBLL
метода классаGetCategories()
. В раскрывающемся спискеListItem
раскрывающихся списков отображаетсяCategoryName
поле данных с использованиемCategoryID
поля данных в качестве значений.SupplierName
Добавьте DropDownList и задайте для нееID
значениеNewSupplierID
. Привяжите его к новому объекту ObjectDataSource с именемSuppliersDataSource
и настройте для использованияSuppliersBLL
метода классаGetSuppliers()
. В раскрывающемся спискеListItem
раскрывающихся списков отображаетсяCompanyName
поле данных с использованиемSupplierID
поля данных в качестве значений.
Для каждого из элементов управления проверки очистите ForeColor
свойство , чтобы FooterStyle
вместо красного цвета по умолчанию использовался белый цвет переднего плана класса CSS. Также используйте ErrorMessage
свойство для подробного описания, но присвойте Text
свойству звездочку. Чтобы текст элемента управления проверки не приводил к переносу интерфейса вставки на две строки, установите FooterStyle
для свойства s Wrap
значение false для каждого элемента FooterTemplate
управления, использующее элемент управления проверки. Наконец, добавьте элемент управления ValidationSummary под GridView и задайте для его ShowMessageBox
свойства значение True
, а для свойства ShowSummary
— значение False
.
При добавлении нового продукта необходимо предоставить CategoryID
и SupplierID
. Эти сведения записываются с помощью DropDownLists в ячейках нижнего CategoryName
колонтитула для полей и SupplierName
. Я решил использовать эти поля вместо CategoryID
и SupplierID
TemplateFields, так как в строках данных сетки пользователь, скорее всего, больше заинтересован в просмотре категорий и поставщиков, а не их идентификаторов. CategoryID
Так как значения и SupplierID
теперь записываются в CategoryName
интерфейсы вставки полей и SupplierName
, мы можем удалить CategoryID
и SupplierID
TemplateFields из GridView.
Аналогичным образом не ProductID
используется при добавлении нового продукта, поэтому ProductID
TemplateField также можно удалить. Однако оставим ProductID
поле в сетке. Помимо элементов управления TextBoxes, DropDownLists, CheckBoxes и проверки, которые составляют интерфейс вставки, нам также потребуется кнопка Добавить, которая при нажатии выполняет логику для добавления нового продукта в базу данных. На шаге 4 мы добавим кнопку Добавить в интерфейс вставки в ProductID
templateField.FooterTemplate
Вы можете улучшить внешний вид различных полей GridView. Например, может потребоваться отформатировать UnitPrice
значения в виде валюты, выровнять поля , UnitsOnOrder
и ReorderLevel
по правому краю UnitsInStock
и обновить HeaderText
значения для TemplateFields.
После создания набора интерфейсов вставки в FooterTemplate
, удаления SupplierID
и CategoryID
TemplateFields и улучшения эстетики сетки за счет форматирования и выравнивания TemplateFields декларативная разметка GridView должна выглядеть примерно так:
<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>
При просмотре в браузере строка нижнего колонтитула GridView теперь включает готовый интерфейс вставки (см. рис. 10). На этом этапе интерфейс вставки не содержит средства, позволяющие пользователю указать, что он ввел данные для нового продукта и хочет вставить новую запись в базу данных. Кроме того, мы еще не рассмотрели, как данные, введенные в нижний колонтитул, преобразуется в новую запись в Products
базе данных. На шаге 4 мы рассмотрим, как включить кнопку Добавить в интерфейс вставки и как выполнить код при обратной отправке при нажатии. На шаге 5 показано, как вставить новую запись с помощью данных из нижнего колонтитула.
Рис. 10. Нижний колонтитул GridView предоставляет интерфейс для добавления новой записи (щелкните для просмотра полноразмерного изображения)
Шаг 4. Включение кнопки "Добавить" в интерфейс вставки
Нам нужно включить кнопку Добавить где-то в интерфейсе вставки, так как в интерфейсе вставки строки нижнего колонтитула в настоящее время отсутствуют средства, позволяющие пользователю указать, что он завершил ввод сведений о новом продукте. Его можно поместить в один из существующих FooterTemplate
объектов или добавить новый столбец в сетку для этой цели. Для работы с этим руководством поместим кнопку Добавить в ProductID
templateField s FooterTemplate
.
В Designer щелкните ссылку Изменить шаблоны в смарт-теге GridView и выберите ProductID
поля FooterTemplate
из раскрывающегося списка. Добавьте веб-элемент управления Button (или LinkButton или ImageButton, если вы предпочитаете) в шаблон, задав для его идентификатора AddProduct
значение , а для свойства CommandName
— значение Добавить, Text
как показано на рисунке 11.
Рис. 11. Поместите кнопку "Добавить" в ProductID
templateField (FooterTemplate
щелкните для просмотра полноразмерного изображения)
После добавления кнопки Добавить проверьте страницу в браузере. Обратите внимание, что при нажатии кнопки Добавить с недопустимыми данными в интерфейсе вставки обратная передача завершается коротко, а элемент управления ValidationSummary указывает на недопустимые данные (см. рис. 12). При вводе соответствующих данных нажатие кнопки Добавить приводит к обратной отправке. Однако запись не добавляется в базу данных. Нам потребуется написать немного кода, чтобы фактически выполнить вставку.
Рис. 12. Обратная передача кнопки "Добавить" является короткой, если в интерфейсе вставки есть недопустимые данные (щелкните для просмотра полноразмерного изображения)
Примечание
Элементы управления проверки в интерфейсе вставки не были назначены группе проверки. Это работает нормально, если интерфейс вставки является единственным набором элементов управления проверки на странице. Однако если на странице есть другие элементы управления проверки (например, элементы управления проверки в интерфейсе редактирования сетки), то элементам управления проверки в интерфейсе вставки и свойствах кнопки ValidationGroup
Добавить следует присвоить то же значение, чтобы связать эти элементы управления с определенной группой проверки. Дополнительные сведения о секционации элементов управления проверкой и кнопок на странице на группы проверки см. в ASP.NET 2.0 .
Шаг 5. Вставка новой записи в таблицуProducts
При использовании встроенных функций редактирования GridView GridView автоматически обрабатывает всю работу, необходимую для выполнения обновления. В частности, при нажатии кнопки Обновить он копирует значения, введенные из интерфейса редактирования, в параметры в коллекции ObjectDataSource UpdateParameters
и запускает обновление, вызывая метод ObjectDataSource Update()
. Так как GridView не предоставляет таких встроенных функций для вставки, необходимо реализовать код, который вызывает метод ObjectDataSource Insert()
и копирует значения из интерфейса вставки в коллекцию ObjectDataSource InsertParameters
.
Эта логика вставки должна выполняться после нажатия кнопки Добавить. Как описано в руководстве По добавлению кнопок в GridView и реагированию на них , при каждом щелчке элемента Button, LinkButton или ImageButton в GridView событие GridView RowCommand
возникает при обратной отправке. Это событие возникает независимо от того, были ли добавлены button, LinkButton или ImageButton явным образом, например кнопка Добавить в строке нижнего колонтитула или автоматически добавлен gridView (например, LinkButtons в верхней части каждого столбца при выборе параметра Включить сортировку или LinkButtons в интерфейсе подкачки при выборе параметра Включить разбиение по страницам).
Поэтому, чтобы ответить на нажатие кнопки Добавить, необходимо создать обработчик событий для события GridView RowCommand
. Так как это событие возникает всякий раз при щелчке элемента Button, LinkButton или ImageButton в GridView, крайне важно, чтобы мы переходили к логике вставки, только если CommandName
свойство, передаваемое в обработчик событий, сопоставляется со значением CommandName
кнопки Добавить ( Вставить ). Кроме того, следует продолжать только в том случае, если элементы управления проверкой сообщают о допустимых данных. Чтобы обеспечить это, создайте обработчик событий для RowCommand
события со следующим кодом:
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
Примечание
Возможно, вас интересует, почему обработчик событий беспокоит проверку Page.IsValid
свойства. В конце концов, не будет ли обратная передача подавляться, если в интерфейсе вставки предоставлены недопустимые данные? Это предположение верно, если пользователь не отключил JavaScript или не принял меры для обхода логики проверки на стороне клиента. Короче говоря, никогда не следует полагаться исключительно на проверку на стороне клиента; перед работой с данными всегда следует выполнять проверка на стороне сервера.
На шаге ProductsDataSource
1 мы создали ObjectDataSource таким образом, чтобы его Insert()
метод сопоставляется с методом ProductsBLL
класса s AddProduct
. Чтобы вставить новую запись в таблицуProducts
, можно просто вызвать метод 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()
метод был вызван, осталось скопировать значения из интерфейса вставки в параметры, передаваемые методу ProductsBLL
класса .AddProduct
Как мы видели в учебнике Изучение событий, связанных с вставкой, обновлением и удалением , это можно сделать с помощью события ObjectDataSource Inserting
. В случае Inserting
, если нам нужно программно ссылаться на элементы управления из строки нижнего Products
колонтитула GridView и присвоить e.InputParameters
их значения коллекции. Если пользователь пропускает значение, например оставляя ReorderLevel
TextBox пустым, необходимо указать, что значение, вставленное в базу данных, должно иметь значение NULL
. AddProducts
Так как метод принимает типы, допускаемые значения NULL, для полей базы данных, допускающих значение NULL, просто используйте тип, допускающий значение NULL, и присвойте ей значение Nothing
в случае, если введенные пользователем данные опущены.
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
После завершения обработчика Inserting
событий новые записи можно добавить в таблицу Products
базы данных с помощью строки нижнего колонтитула GridView. Попробуйте добавить несколько новых продуктов.
Улучшение и настройка операции добавления
В настоящее время нажатие кнопки Добавить добавляет новую запись в таблицу базы данных, но не предоставляет никаких визуальных отзывов о том, что запись успешно добавлена. В идеале поле оповещения На стороне клиента или веб-элемента управления "Метка" информирует пользователя о том, что вставка выполнена успешно. Я оставляю это как упражнение для читателя.
GridView, используемый в этом руководстве, не применяет порядок сортировки к перечисленным продуктам и не позволяет конечному пользователю сортировать данные. Следовательно, записи упорядочены в том виде, в который они находятся в базе данных, по полю первичного ключа. Так как каждая новая запись имеет ProductID
значение больше, чем последняя, каждый раз при добавлении нового продукта он добавляется в конец сетки. Поэтому может потребоваться автоматически отправить пользователя на последнюю страницу GridView после добавления новой записи. Это можно сделать, добавив следующую строку кода после вызова ProductsDataSource.Insert()
в RowCommand
обработчике событий, чтобы указать, что пользователь должен быть отправлен на последнюю страницу после привязки данных к GridView:
' Indicate that the user needs to be sent to the last page
SendUserToLastPage = True
SendUserToLastPage
— это логическая переменная уровня страницы, которая изначально имеет значение False
. Если в обработчике SendUserToLastPage
событий GridView DataBound
имеет значение false, PageIndex
свойство обновляется для отправки пользователя на последнюю страницу.
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
Причина, PageIndex
по которой свойство задается в обработчике DataBound
событий (в отличие от RowCommand
обработчика событий), заключается в том, что при RowCommand
срабатывании обработчика событий мы еще не добавили новую запись в таблицу Products
базы данных. Таким образом, в обработчике RowCommand
событий индекс последней страницы (PageCount - 1
) представляет индекс последней страницы перед добавлением нового продукта. Для большинства добавляемых продуктов индекс последней страницы после добавления нового продукта совпадает. Но когда добавленный продукт приводит к новому индексу последней страницы, если мы неправильно обновим PageIndex
в RowCommand
обработчике событий, мы перейдем на вторую до последней страницы (индекс последней страницы перед добавлением нового продукта) в отличие от нового индекса последней страницы. DataBound
Так как обработчик событий срабатывает после добавления нового продукта и отскок данных в сетку, задавая PageIndex
там свойство, мы знаем, что получаем правильный индекс последней страницы.
Наконец, GridView, используемый в этом руководстве, довольно широк из-за количества полей, которые необходимо собрать для добавления нового продукта. Из-за такой ширины может быть предпочтителен вертикальный макет DetailsView. Общую ширину GridView можно уменьшить, собирая меньше входных данных. Возможно, нам не нужно собирать UnitsOnOrder
поля , UnitsInStock
и ReorderLevel
при добавлении нового продукта. В этом случае эти поля можно удалить из GridView.
Чтобы настроить собранные данные, можно использовать один из двух подходов:
- Продолжайте использовать
AddProduct
метод , который ожидает значения дляUnitsOnOrder
полей ,UnitsInStock
иReorderLevel
. В обработчикеInserting
событий укажите жестко заданные значения по умолчанию для этих входных данных, которые были удалены из интерфейса вставки. - Создайте перегрузку
AddProduct
метода вProductsBLL
классе , которая не принимает входные данные дляUnitsOnOrder
полей ,UnitsInStock
иReorderLevel
. Затем на странице ASP.NET настройте ObjectDataSource для использования этой новой перегрузки.
Любой из вариантов будет работать одинаково. В предыдущих руководствах мы использовали последний вариант, создавая несколько перегрузок для ProductsBLL
метода класса UpdateProduct
.
Сводка
GridView не имеет встроенных возможностей вставки, доступных в DetailsView и FormView, но с немного усилий интерфейс вставки можно добавить в строку нижнего колонтитула. Чтобы отобразить строку нижнего колонтитула в GridView, просто присвойте свойству ShowFooter
значение True
. Содержимое строки нижнего колонтитула можно настроить для каждого поля, преобразовав поле в TemplateField и добавив интерфейс вставки в FooterTemplate
. Как мы видели в этом руководстве FooterTemplate
, может содержать button, TextBoxes, DropDownLists, CheckBoxes, элементы управления источником данных для заполнения управляемых данными веб-элементов управления (например, DropDownLists) и элементов управления проверки. Наряду с элементами управления для сбора данных, введенных пользователем, требуется кнопка "Добавить", "LinkButton" или "ImageButton".
При нажатии кнопки Добавить вызывается метод ObjectDataSource для Insert()
запуска рабочего процесса вставки. Затем ObjectDataSource вызовет настроенный метод insert ( ProductsBLL
метод класса s AddProduct
в этом руководстве). Необходимо скопировать значения из интерфейса вставки GridView в коллекцию ObjectDataSource InsertParameters
перед вызовом метода insert. Это можно сделать путем программной ссылки на веб-элементы управления интерфейса вставки в обработчике событий ObjectDataSource Inserting
.
В этом руководстве мы рассмотрим методы улучшения внешнего вида GridView. В следующем наборе учебников рассматривается работа с двоичными данными, такими как изображения, PDF-файлы, документы Word и т. д., а также веб-элементы управления данными.
Счастливого программирования!
Об авторе
Скотт Митчелл( Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Он может быть доступен в mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.
Особая благодарность
Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущим рецензентом этого руководства была Бернадетт Ли. Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.