Поделиться через


Настройка интерфейса правки элемента управления DataList (VB)

Скотт Митчелл

Скачать в формате PDF

В этом руководстве мы создадим более широкий интерфейс редактирования для DataList, который включает DropDownLists и CheckBox.

Введение

Разметка и веб-элементы управления в DataList EditItemTemplate определяют его редактируемый интерфейс. Во всех редактируемых примерах DataList, которые мы изучили до сих пор, редактируемый интерфейс был состоит из веб-элементов управления TextBox. В предыдущем руководстве мы улучшили взаимодействие с пользователем во время редактирования, добавив элементы управления проверкой.

Его EditItemTemplate можно расширить, чтобы включить веб-элементы управления, отличные от TextBox, например DropDownLists, RadioButtonLists, Calendars и т. д. Как и в TextBoxes, при настройке интерфейса редактирования для включения других веб-элементов управления выполните следующие действия.

  1. Добавьте веб-элемент управления в EditItemTemplateэлемент управления .
  2. Используйте синтаксис привязки данных, чтобы назначить соответствующее значение поля данных соответствующему свойству.
  3. В обработчике 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 (Нет).

Задайте раскрывающимся спискам раскрывающихся списков вкладок 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.

Создание объекта ObjectDataSource с именем CategoriesDataSource

Рис. 5. Создание объекта ObjectDataSource С именем CategoriesDataSource (щелкните, чтобы просмотреть изображение полного размера)

Настройка полей отображения и значения dropDownList

Рис. 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

Снимок экрана: DataList EditItemTemplate после добавления обработчиков событий EditCommand и CancelCommand и кнопки

Рис. 8. Нажатие кнопки "Изменить" отображает интерфейс редактирования (щелкните, чтобы просмотреть изображение полного размера)

Шаг 4. Добавление синтаксиса DataBinding в интерфейс редактирования

Чтобы интерфейс редактирования отображал текущие значения продукта, необходимо использовать синтаксис привязки данных для назначения значений поля данных соответствующим значениям веб-элемента управления. Синтаксис привязки данных можно применить с помощью конструктора, перейдя на экран "Изменить шаблоны" и выбрав ссылку "Изменить dataBindings" из смарт-тегов веб-элементов управления. Кроме того, синтаксис привязки данных можно добавить непосредственно в декларативную разметку.

ProductName Назначьте значение поля данных свойству ProductName TextBox, SupplierID CategoryID значения Categories поля данных свойствам и Suppliers dropDownLists SelectedValue и Discontinued значению поля данных свойству Discontinued CheckBox Text Checked. После внесения этих изменений с помощью конструктора или непосредственно через декларативную разметку просмотрите страницу через браузер и нажмите кнопку "Изменить" для Шеф-повара Антона с Гамбо Микс. Как показано на рисунке 9, синтаксис привязки данных добавил текущие значения в TextBox, DropDownLists и CheckBox.

Снимок экрана: DataList EditItemTemplate после добавления синтаксиса DataBinding и выбрана кнопка

Рис. 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) в начале раскрывающегося списка.

В раскрывающихся списках категорий и поставщиков включен параметр (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.