Настройка интерфейса правки элемента управления DataList (VB)
В этом руководстве мы создадим расширенный интерфейс редактирования для DataList, который включает DropDownLists и CheckBox.
Введение
Элементы управления разметкой и веб-элементы управления в элементах EditItemTemplate
DataList определяют его редактируемый интерфейс. Во всех редактируемых примерах DataList, которые мы рассмотрели до сих пор, редактируемый интерфейс состоит из веб-элементов управления TextBox. В предыдущем руководстве мы улучшили взаимодействие с пользователем во время редактирования, добавив элементы управления проверкой.
Можно EditItemTemplate
дополнительно развернуть, чтобы включить веб-элементы управления, отличные от TextBox, такие как DropDownLists, RadioButtonLists, Calendars и т. д. Как и в случае с TextBoxes, при настройке интерфейса редактирования для включения других веб-элементов управления выполните следующие действия.
- Добавьте веб-элемент управления в .
EditItemTemplate
- Используйте синтаксис привязки данных, чтобы назначить соответствующее значение поля данных соответствующему свойству.
- В обработчике
UpdateCommand
событий программным способом получите доступ к значению веб-элемента управления и передайте его в соответствующий метод BLL.
В этом руководстве мы создадим расширенный интерфейс редактирования для DataList, который включает DropDownLists и CheckBox. В частности, мы создадим dataList, который содержит сведения о продукте и разрешает обновлять название продукта, поставщик, категорию и состояние прекращения (см. рис. 1).
Рис. 1. Интерфейс редактирования включает textBox, два раскрывающихся списка и флажок (щелкните для просмотра полноразмерного изображения)
Шаг 1. Отображение сведений о продукте
Прежде чем создать редактируемый интерфейс DataList, необходимо сначала создать интерфейс только для чтения. Начните с открытия CustomizedUI.aspx
страницы в папке EditDeleteDataList
и из Designer добавьте dataList на страницу, задав для ее ID
свойства значение Products
. В смарт-теге DataList создайте объект ObjectDataSource. Присвойте этому новому объекту имя ObjectDataSource ProductsDataSource
и настройте его для получения данных из ProductsBLL
метода класса .GetProducts
Как и в предыдущих руководствах по dataList, мы обновим измененные сведения о продукте, перейдя непосредственно на уровень бизнес-логики. Соответственно, установите для раскрывающихся списков на вкладках UPDATE, INSERT и DELETE значение (Нет).
Рис. 2. Задайте для Drop-Down Списки вкладок UPDATE, INSERT и DELETE значение (Нет) (щелкните для просмотра полноразмерного изображения)
После настройки ObjectDataSource Visual Studio создаст для DataList по умолчанию ItemTemplate
имя и значение для каждого возвращаемого поля данных. Измените , ItemTemplate
чтобы в шаблоне отображалось название продукта в <h4>
элементе вместе с именем категории, именем поставщика, ценой и состоянием прекращения. Кроме того, добавьте кнопку Изменить, чтобы убедиться, что ее CommandName
свойство имеет значение Изменить. Декларативная разметка для моего 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 для категории, другой для поставщика и CheckBox для состояния прекращения работы. Так как цена продукта в этом примере не редактируется, мы можем продолжать отображать ее с помощью веб-элемента управления Label Web.
Чтобы настроить интерфейс редактирования, щелкните ссылку Изменить шаблоны в смарт-теге 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 для поставщиков. ID
Задайте для этого DropDownList значение и присвойте Suppliers
ей имя ObjectDataSource SuppliersDataSource
.
После добавления двух DropDownLists добавьте CheckBox для состояния прекращения работы и TextBox для названия продукта. Задайте для ID
checkBox и TextBox Discontinued
значения и ProductName
соответственно. Добавьте RequiredFieldValidator, чтобы убедиться, что пользователь предоставляет значение для названия продукта.
Наконец, добавьте кнопки Обновить и Отмена. Помните, что для этих двух кнопок крайне важно, чтобы их CommandName
свойства были установлены в значения Обновить и Отмена соответственно.
Не стесняйтесь выложить интерфейс редактирования, как вам нравится. Я решил использовать тот же макет с четырьмя столбцами <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. Интерфейс редактирования расположен так же, как интерфейс Read-Only (щелкните для просмотра полноразмерного изображения)
Шаг 3. Создание обработчиков событий EditCommand и CancelCommand
В настоящее время нет синтаксиса привязки данных в EditItemTemplate
(за UnitPriceLabel
исключением , который был скопирован в буквальном формате из ItemTemplate
). Мы добавим синтаксис привязки данных на мгновение, но сначала создадим обработчики событий для событий DataList EditCommand
и CancelCommand
. Помните, что обработчик событий отвечает за EditCommand
отрисовку CancelCommand
интерфейса редактирования для элемента DataList, для которого была нажата кнопка "Изменить", в то время как задание состоит в том, чтобы вернуть 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 показан список данных после нажатия кнопки Изменить для Chef Anton s Gumbo Mix. Так как мы еще не добавили синтаксис привязки данных в интерфейс редактирования, ProductName
элемент TextBox пуст, Discontinued
флажок CheckBox снят, а первые элементы, выбранные из Categories
и Suppliers
DropDownLists, не добавлены.
Рис. 8. Нажатие кнопки "Изменить" отображает интерфейс редактирования (щелкните для просмотра полноразмерного изображения)
Шаг 4. Добавление синтаксиса DataBinding в интерфейс редактирования
Чтобы в интерфейсе редактирования отображались текущие значения продукта, необходимо использовать синтаксис привязки данных для назначения значений полей данных соответствующим значениям веб-элемента управления. Синтаксис привязки данных можно применить через Designer, перейдя на экран Изменение шаблонов и выбрав ссылку Изменить dataBindings в смарт-тегах веб-элементов управления. Кроме того, синтаксис привязки данных можно добавить непосредственно в декларативную разметку.
ProductName
Назначьте значение поля данных свойству ProductName
TextBox sText
, CategoryID
значения Categories
поля данных и SupplierID
свойствам и Suppliers
DropDownListsSelectedValue
, а Discontinued
значение поля данных — свойству Discontinued
CheckBox sChecked
. После внесения этих изменений либо через Designer, либо непосредственно через декларативную разметку, вернитесь на страницу в браузере и нажмите кнопку Изменить для Chef Anton s Gumbo Mix. Как показано на рисунке 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-Level , чтобы сохранить код и этот пример в фокусе. В качестве упражнения добавьте эту функцию после завершения работы с этим руководством.
Шаг 6. Обработка значений CategoryID и SupplierID со значением NULL
База данных Northwind позволяет использовать NULL
значения для Products
столбцов CategoryID
таблицы и SupplierID
. Однако наш интерфейс редактирования в настоящее время не поддерживает NULL
значения. При попытке изменить продукт, имеющий NULL
значение для столбцов CategoryID
или SupplierID
, мы получим ArgumentOutOfRangeException
сообщение об ошибке, примерно следующее: "Categories" имеет значение SelectedValue, которое является недопустимым, так как оно не существует в списке элементов. Кроме того, в настоящее время нет способа изменить категорию продукта или значение поставщика с не-значенияNULL
на значение, отличное NULL
от значения.
Чтобы поддерживать NULL
значения для категории и dropDownLists поставщика, необходимо добавить дополнительный ListItem
. Я решил использовать (Нет) в 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
можно добавить в Раскрывающийся список с помощью Designer или непосредственно с помощью декларативного синтаксиса. При добавлении элемента DropDownList для представления значения базы данных NULL
обязательно добавьте ListItem
с помощью декларативного синтаксиса. Если вы используете ListItem
Редактор Collection в Designer, созданный декларативный синтаксис будет полностью пропускать Value
параметр при назначении пустой строки, создавая декларативную разметку, например: <asp:ListItem>(None)</asp:ListItem>
. Хотя это может выглядеть безобидно, отсутствие Value
приводит к тому, что DropDownList будет использовать Text
значение свойства вместо нее. Это означает, что если этот NULL
ListItem
параметр выбран, будет предпринята попытка назначить значение (None) полю данных продукта (CategoryID
или SupplierID
, в этом руководстве), что приведет к исключению. При явном задании Value=""
NULL
значение будет присваиваться полю данных продукта при выборе NULL
ListItem
.
Уделите немного времени, чтобы просмотреть наш прогресс в браузере. При редактировании продукта обратите внимание, что Categories
и Suppliers
DropDownLists имеют параметр (Нет) в начале DropDownList.
Рис. 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
. При учете для NULL
необходимо не только правильно отобразить существующее NULL
значение в интерфейсе редактирования, но и предложить средство для пометки значения как NULL
. Для DropDownLists в DataLists обычно это означает добавление статического ListItem
объекта, свойство которого Value
явно задано в пустую строку (Value=""
), и добавление в обработчик событий немного кода UpdateCommand
, чтобы определить, был ли NULL``ListItem
выбран объект .
Счастливого программирования!
Об авторе
Скотт Митчелл( 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.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по