Настройка интерфейса правки элемента управления DataList (VB)
В этом руководстве мы создадим более широкий интерфейс редактирования для DataList, который включает DropDownLists и CheckBox.
Введение
Разметка и веб-элементы управления в DataList EditItemTemplate
определяют его редактируемый интерфейс. Во всех редактируемых примерах DataList, которые мы изучили до сих пор, редактируемый интерфейс был состоит из веб-элементов управления TextBox. В предыдущем руководстве мы улучшили взаимодействие с пользователем во время редактирования, добавив элементы управления проверкой.
Его EditItemTemplate
можно расширить, чтобы включить веб-элементы управления, отличные от TextBox, например DropDownLists, RadioButtonLists, Calendars и т. д. Как и в TextBoxes, при настройке интерфейса редактирования для включения других веб-элементов управления выполните следующие действия.
- Добавьте веб-элемент управления в
EditItemTemplate
элемент управления . - Используйте синтаксис привязки данных, чтобы назначить соответствующее значение поля данных соответствующему свойству.
- В обработчике
UpdateCommand
событий программным образом обращается к значению веб-элемента управления и передает его в соответствующий метод BLL.
В этом руководстве мы создадим более широкий интерфейс редактирования для DataList, который включает DropDownLists и CheckBox. В частности, мы создадим DataList, который содержит сведения о продукте и разрешает обновлять имя продукта, поставщик, категорию и прекращенное состояние (см. рис. 1).
Рис. 1. Интерфейс редактирования включает текстовое поле, два раскрывающихся списка и флажок (щелкните, чтобы просмотреть изображение полного размера)
Шаг 1. Отображение сведений о продукте
Прежде чем создать редактируемый интерфейс DataList, сначала необходимо создать интерфейс только для чтения. Начните с открытия CustomizedUI.aspx
страницы из папки и добавьте DataList на EditDeleteDataList
страницу с помощью конструктора, указав для свойства значение ID
Products
. Создайте объект ObjectDataSource из смарт-тега DataList. Назовите этот новый ObjectDataSource ProductsDataSource
и настройте его для получения данных из ProductsBLL
метода класса GetProducts
. Как и в предыдущих руководствах по редактированию DataList, мы обновим измененные сведения о продукте, перейдя непосредственно на уровень бизнес-логики. Соответственно, задайте раскрывающийся список на вкладках UPDATE, INSERT и DELETE (Нет).
Рис. 2. Установка раскрывающихся списков вкладок UPDATE, INSERT и DELETE (Нет) (Щелкните, чтобы просмотреть изображение полного размера)
После настройки ObjectDataSource Visual Studio создаст значение по умолчанию ItemTemplate
для DataList, который содержит имя и значение для каждого возвращаемого поля данных. ItemTemplate
Измените шаблон таким образом, чтобы шаблон перечислял имя продукта в <h4>
элементе вместе с именем категории, именем поставщика, ценой и прекращенным состоянием. Кроме того, добавьте кнопку "Изменить", убедившись, что его CommandName
свойство имеет значение Edit. Декларативная разметка для моего ItemTemplate
следующего:
<ItemTemplate>
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>' />
</h4>
<table border="0">
<tr>
<td class="ProductPropertyLabel">Category:</td>
<td class="ProductPropertyValue">
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>' />
</td>
<td class="ProductPropertyLabel">Supplier:</td>
<td class="ProductPropertyValue">
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>' />
</td>
</tr>
<tr>
<td class="ProductPropertyLabel">Discontinued:</td>
<td class="ProductPropertyValue">
<asp:Label ID="DiscontinuedLabel" runat="server"
Text='<%# Eval("Discontinued") %>' />
</td>
<td class="ProductPropertyLabel">Price:</td>
<td class="ProductPropertyValue">
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
</td>
</tr>
<tr>
<td colspan="4">
<asp:Button runat="Server" ID="EditButton"
Text="Edit" CommandName="Edit" />
</td>
</tr>
</table>
<br />
</ItemTemplate>
Приведенная выше разметка содержит сведения о продукте с использованием <заголовка h4> для имени продукта и четырех столбца <table>
для оставшихся полей. Классы ProductPropertyLabel
и ProductPropertyValue
CSS, определенные в Styles.css
, были рассмотрены в предыдущих руководствах. На рисунке 3 показан прогресс при просмотре через браузер.
Рис. 3. Отображается имя, поставщик, категория, прекращенное состояние и цена каждого продукта (щелкните, чтобы просмотреть изображение полного размера)
Шаг 2. Добавление веб-элементов управления в интерфейс редактирования
Первым шагом в создании настраиваемого интерфейса редактирования DataList является добавление необходимых веб-элементов управления в EditItemTemplate
. В частности, нам нужен DropDownList для категории, другой для поставщика, а также флажок для прекращенного состояния. Так как цена продукта не редактируется в этом примере, мы можем продолжать отображать его с помощью веб-элемента управления Label.
Чтобы настроить интерфейс редактирования, щелкните ссылку "Изменить шаблоны" из смарт-тега DataList и выберите EditItemTemplate
вариант из раскрывающегося списка. Добавьте dropDownList в список и задайте для нее EditItemTemplate
значение ID
Categories
.
Рис. 4. Добавление раскрывающегося списка для категорий (щелкните, чтобы просмотреть изображение полного размера)
Затем в смарт-теге DropDownList выберите параметр "Выбрать источник данных" и создайте новый объект ObjectDataSource с именем CategoriesDataSource
. Настройте этот объект ObjectDataSource для использования CategoriesBLL
метода класса GetCategories()
(см. рис. 5). Затем мастер настройки источника данных dropDownList запрашивает поля данных, которые будут использоваться для каждого ListItem
из Text
них и Value
свойств. В раскрывающемся списке отображается CategoryName
поле данных и используется CategoryID
в качестве значения, как показано на рис. 6.
Рис. 5. Создание объекта ObjectDataSource С именем CategoriesDataSource
(щелкните, чтобы просмотреть изображение полного размера)
Рис. 6. Настройка полей отображения и значения dropDownList (щелкните, чтобы просмотреть изображение полного размера)
Повторите этот ряд шагов, чтобы создать DropDownList для поставщиков. ID
Задайте для этого раскрывающегося Suppliers
списка имя и присвойте ей имя ObjectDataSourceSuppliersDataSource
.
После добавления двух раскрывающихся списков добавьте флажок для прекращенного состояния и Текстовое поле для имени продукта. Задайте значения ID
s для checkBox и TextBox Discontinued
ProductName
соответственно. Добавьте RequiredFieldValidator, чтобы убедиться, что пользователь предоставляет значение имени продукта.
Наконец, добавьте кнопки "Обновить" и "Отмена". Помните, что для этих двух кнопок крайне важно, чтобы их CommandName
свойства были заданы как Update и Cancel соответственно.
Вы можете выложить интерфейс редактирования, но вам нравится. Я решил использовать тот же макет четырех столбцов <table>
из интерфейса только для чтения, как показано в следующем декларативном синтаксисе и снимке экрана:
<EditItemTemplate>
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>' />
</h4>
<table border="0">
<tr>
<td class="ProductPropertyLabel">Name:</td>
<td colspan="3" class="ProductPropertyValue">
<asp:TextBox runat="server" ID="ProductName" Width="90%" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must enter a name for the product."
runat="server">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td class="ProductPropertyLabel">Category:</td>
<td class="ProductPropertyValue">
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID" />
</td>
<td class="ProductPropertyLabel">Supplier:</td>
<td class="ProductPropertyValue">
<asp:DropDownList ID="Suppliers"
DataSourceID="SuppliersDataSource" DataTextField="CompanyName"
DataValueField="SupplierID" runat="server" />
</td>
</tr>
<tr>
<td class="ProductPropertyLabel">Discontinued:</td>
<td class="ProductPropertyValue">
<asp:CheckBox runat="server" id="Discontinued" />
</td>
<td class="ProductPropertyLabel">Price:</td>
<td class="ProductPropertyValue">
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
</td>
</tr>
<tr>
<td colspan="4">
<asp:Button runat="Server" ID="UpdateButton" CommandName="Update"
Text="Update" />
<asp:Button runat="Server" ID="CancelButton" CommandName="Cancel"
Text="Cancel" CausesValidation="False" />
</td>
</tr>
</table>
<br />
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"
TypeName="CategoriesBLL">
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers"
TypeName="SuppliersBLL">
</asp:ObjectDataSource>
</EditItemTemplate>
Рис. 7. Интерфейс редактирования выложен, как интерфейс только для чтения (щелкните, чтобы просмотреть изображение полного размера)
Шаг 3. Создание обработчиков событий EditCommand и CancelCommand
В настоящее время в EditItemTemplate
синтаксисе привязки данных нет (за исключением UnitPriceLabel
синтаксиса, скопированного через подробные данные из ).ItemTemplate
Мы добавим синтаксис привязки данных мгновенно, но сначала создадим обработчики событий для dataList EditCommand
и CancelCommand
событий. Помните, что ответственность EditCommand
обработчика событий заключается в отрисовке интерфейса редактирования элемента DataList с нажатием кнопки "Изменить", а CancelCommand
задание состоит в том, чтобы вернуть DataList в его состояние предварительного редактирования.
Создайте эти два обработчика событий и используйте следующий код:
Protected Sub Products_EditCommand(source As Object, e As DataListCommandEventArgs) _
Handles Products.EditCommand
' Set the DataList's EditItemIndex property to the
' index of the DataListItem that was clicked
Products.EditItemIndex = e.Item.ItemIndex
' Rebind the data to the DataList
Products.DataBind()
End Sub
Protected Sub Products_CancelCommand(source As Object, e As DataListCommandEventArgs) _
Handles Products.CancelCommand
' Set the DataList's EditItemIndex property to -1
Products.EditItemIndex = -1
' Rebind the data to the DataList
Products.DataBind()
End Sub
При использовании этих двух обработчиков событий нажатие кнопки "Изменить" отображает интерфейс редактирования и нажатие кнопки "Отмена" возвращает измененный элемент в режим только для чтения. На рисунке 8 показан список данных после нажатия кнопки "Изменить" для Шеф-повара Антона с Гамбо Микс. Так как мы еще не добавили любой синтаксис привязки данных в интерфейс редактирования, TextBox пустой, ProductName
Discontinued
флажок снят и первые элементы, выбранные в Categories
раскрывающемся списке.Suppliers
Рис. 8. Нажатие кнопки "Изменить" отображает интерфейс редактирования (щелкните, чтобы просмотреть изображение полного размера)
Шаг 4. Добавление синтаксиса DataBinding в интерфейс редактирования
Чтобы интерфейс редактирования отображал текущие значения продукта, необходимо использовать синтаксис привязки данных для назначения значений поля данных соответствующим значениям веб-элемента управления. Синтаксис привязки данных можно применить с помощью конструктора, перейдя на экран "Изменить шаблоны" и выбрав ссылку "Изменить dataBindings" из смарт-тегов веб-элементов управления. Кроме того, синтаксис привязки данных можно добавить непосредственно в декларативную разметку.
ProductName
Назначьте значение поля данных свойству ProductName
TextBox, SupplierID
CategoryID
значения Categories
поля данных свойствам и Suppliers
dropDownLists SelectedValue
и Discontinued
значению поля данных свойству Discontinued
CheckBox Text
Checked
. После внесения этих изменений с помощью конструктора или непосредственно через декларативную разметку просмотрите страницу через браузер и нажмите кнопку "Изменить" для Шеф-повара Антона с Гамбо Микс. Как показано на рисунке 9, синтаксис привязки данных добавил текущие значения в TextBox, DropDownLists и CheckBox.
Рис. 9. Нажатие кнопки "Изменить" отображает интерфейс редактирования (щелкните, чтобы просмотреть изображение полного размера)
Шаг 5. Сохранение изменений пользователя в обработчике событий UpdateCommand
Когда пользователь редактирует продукт и нажимает кнопку "Обновить", происходит обратная передача и событие DataList UpdateCommand
запускается. В обработчике событий необходимо считывать значения из веб-элементов управления в EditItemTemplate
веб-элементах управления и интерфейсе с BLL, чтобы обновить продукт в базе данных. Как мы видели в предыдущих руководствах, ProductID
обновленный продукт доступен через коллекцию DataKeys
. Доступ к полям, введенным пользователем, программным способом ссылается на веб-элементы управления, используя FindControl("controlID")
следующий код:
Protected Sub Products_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
Handles Products.UpdateCommand
If Not Page.IsValid Then
Exit Sub
End If
' Read in the ProductID from the DataKeys collection
Dim productID As Integer = Convert.ToInt32(Products.DataKeys(e.Item.ItemIndex))
' Read in the product name and price values
Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
Dim categories As DropDownList=CType(e.Item.FindControl("Categories"), DropDownList)
Dim suppliers As DropDownList = CType(e.Item.FindControl("Suppliers"), DropDownList)
Dim discontinued As CheckBox = CType(e.Item.FindControl("Discontinued"), CheckBox)
Dim productNameValue As String = Nothing
If productName.Text.Trim().Length > 0 Then
productNameValue = productName.Text.Trim()
End If
Dim categoryIDValue As Integer = Convert.ToInt32(categories.SelectedValue)
Dim supplierIDValue As Integer = Convert.ToInt32(suppliers.SelectedValue)
Dim discontinuedValue As Boolean = discontinued.Checked
' Call the ProductsBLL's UpdateProduct method...
Dim productsAPI As New ProductsBLL()
productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue, _
discontinuedValue, productID)
' Revert the DataList back to its pre-editing state
Products.EditItemIndex = -1
Products.DataBind()
End Sub
Код начинается с консультаций Page.IsValid
по свойству, чтобы убедиться, что все элементы управления проверкой на странице действительны. Если Page.IsValid
это True
так, то измененное значение продукта ProductID
считывается из DataKeys
коллекции, а веб-элементы управления записи данных в них EditItemTemplate
ссылаются программным образом. Затем значения этих веб-элементов управления считываются в переменные, которые затем передаются в соответствующую UpdateProduct
перегрузку. После обновления данных dataList возвращается в состояние предварительного редактирования.
Примечание.
Я опустил логику обработки исключений, добавленную в учебнике по обработке исключений уровня BLL и DAL, чтобы сохранить код и этот пример сосредоточен. В качестве упражнения добавьте эту функцию после завершения работы с этим руководством.
Шаг 6. Обработка значений NULL CategoryID и SupplierID
База данных Northwind позволяет использовать NULL
значения для Products
таблиц CategoryID
и SupplierID
столбцов. Однако наш интерфейс редактирования в настоящее время не соответствует NULL
значениям. Если мы пытаемся изменить продукт, NULL
имеющий значение для его CategoryID
или SupplierID
столбцов, мы получим ArgumentOutOfRangeException
сообщение об ошибке, аналогичное: "Категории" имеет значение SelectedValue, которое является недопустимым, так как оно не существует в списке элементов. Кроме того, в настоящее время нет способа изменить категорию продукта или значение поставщика с не-значенияNULL
на NULL
одно.
Чтобы поддерживать NULL
значения для категории и поставщика DropDownLists, необходимо добавить дополнительный ListItem
. Я выбрал использовать (None) в качестве Text
значения для этого ListItem
, но вы можете изменить его на что-то другое (например, пустую строку), если вы хотите. Наконец, не забудьте задать значение DropDownLists AppendDataBoundItems
True
; если вы забыли сделать это, категории и поставщики, привязанные к DropDownList, перезаписывают статически добавленные ListItem
.
После внесения этих изменений разметка DropDownLists в DataList должна EditItemTemplate
выглядеть следующим образом:
<asp:DropDownList ID="Categories" DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID" runat="server"
SelectedValue='<%# Eval("CategoryID") %>' AppendDataBoundItems="True">
<asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
...
<asp:DropDownList ID="Suppliers" DataSourceID="SuppliersDataSource"
DataTextField="CompanyName" DataValueField="SupplierID" runat="server"
SelectedValue='<%# Eval("SupplierID") %>' AppendDataBoundItems="True">
<asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
Примечание.
Статические ListItem
s можно добавить в DropDownList через конструктор или напрямую через декларативный синтаксис. При добавлении элемента DropDownList для представления значения базы данных NULL
обязательно добавьте его ListItem
с помощью декларативного синтаксиса. Если вы используете ListItem
редактор коллекции в конструкторе, созданный декларативный синтаксис полностью опустит Value
параметр при назначении пустой строки, создав декларативную разметку, например: <asp:ListItem>(None)</asp:ListItem>
Хотя это может выглядеть безвредно, отсутствующие Value
вызывают dropDownList использовать Text
значение свойства в своем месте. Это означает, что при выборе значения NULL
ListItem
(None) будет предпринята попытка назначить поле данных продукта (CategoryID
или SupplierID
, в этом руководстве), что приведет к исключению. Явно задав Value=""
NULL
значение, которое будет назначено полю данных продукта при выборе NULL
ListItem
.
Ознакомьтесь с нашим прогрессом в браузере. При редактировании продукта обратите внимание, что Categories
и Suppliers
DropDownLists имеют параметр (None) в начале раскрывающегося списка.
Рис. 10. В Categories
раскрывающемся Suppliers
списке включен параметр (Нет) (щелкните, чтобы просмотреть изображение полного размера)
Чтобы сохранить параметр (None) в качестве значения базы данных NULL
, необходимо вернуться в UpdateCommand
обработчик событий. Измените целые categoryIDValue
числа и supplierIDValue
переменные, допускающие значение NULL, и назначьте их значение, отличное от значения, отличного Nothing
от того, что dropDownList SelectedValue
не является пустой строкой:
Dim categoryIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(categories.SelectedValue) Then
categoryIDValue = Convert.ToInt32(categories.SelectedValue)
End If
Dim supplierIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(suppliers.SelectedValue) Then
supplierIDValue = Convert.ToInt32(suppliers.SelectedValue)
End If
При этом изменении значение Nothing
будет передано в UpdateProduct
метод BLL, если пользователь выбрал параметр (None) из раскрывающихся списков, соответствующий NULL
значению базы данных.
Итоги
В этом руководстве мы узнали, как создать более сложный интерфейс редактирования DataList, который включал три различных входных веб-элемента управления TextBox, два DropDownLists и CheckBox вместе с элементами управления проверкой. При создании интерфейса редактирования шаги одинаковы независимо от используемых веб-элементов управления: начните с добавления веб-элементов управления в DataList EditItemTemplate
; используйте синтаксис привязки данных для назначения соответствующих значений полей данных с соответствующими свойствами веб-элемента управления; и UpdateCommand
в обработчике событий программным образом обращается к веб-элементам управления и их соответствующим свойствам. передает значения в BLL.
При создании интерфейса редактирования, независимо от того, состоит ли он только из TextBoxes или коллекции различных веб-элементов управления, обязательно правильно обрабатывайте значения базы данных NULL
. При учете s NULL
необходимо не только правильно отображать существующее NULL
значение в интерфейсе редактирования, но и предлагать средства для маркировки значения как NULL
. Для DropDownLists в DataLists обычно это означает добавление статического свойства ListItem
, свойство которого Value
явно задано в пустую строку (Value=""
) и добавление бита кода в UpdateCommand
обработчик событий, чтобы определить, был ли NULL``ListItem
выбран параметр.
Счастливое программирование!
Об авторе
Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 2.0 в 24 часах. Он может быть достигнут в mitchell@4GuysFromRolla.com. или через его блог, который можно найти на http://ScottOnWriting.NET.
Особое спасибо
Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты для этого руководства были Деннис Паттерсон, Дэвид Суру и Рэнди Шмидт. Хотите просмотреть мои предстоящие статьи MSDN? Если да, упадите меня линию в mitchell@4GuysFromRolla.com.