Настройка интерфейса правки элемента управления DataList (C#)
В этом руководстве мы создадим более широкий интерфейс редактирования для DataList, который включает DropDownLists и CheckBox.
Введение
Элементы управления Разметка и Веб в DataList EditItemTemplate
определяют его редактируемый интерфейс. Во всех редактируемых примерах 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
метода класса s 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
. В частности, нам нужен раскрывающийся список для категории, другой для поставщика и CheckBox для состояния прекращения работы. Так как цена продукта в этом примере не редактируется, мы можем продолжать отображать ее с помощью веб-элемента управления Label.
Чтобы настроить интерфейс редактирования, щелкните ссылку Изменить шаблоны в смарт-теге DataList и выберите EditItemTemplate
параметр в раскрывающемся списке. Добавьте раскрывающийся список в и задайте для нее EditItemTemplate
ID
значение Categories
.
Рис. 4. Добавление раскрывающегося списка для категорий (щелкните для просмотра полноразмерного изображения)
Затем в смарт-теге DropDownList выберите параметр Выбрать источник данных и создайте объект ObjectDataSource с именем CategoriesDataSource
. Настройте этот объект ObjectDataSource для использования CategoriesBLL
метода класса ( GetCategories()
см. рис. 5). Затем мастер настройки источника данных DropDownList запрашивает поля данных, которые будут использоваться для каждого свойства ListItem
Text
и Value
. Чтобы в раскрывающемся списке отображалось CategoryName
поле данных, используйте в CategoryID
качестве значения , как показано на рисунке 6.
Рис. 5. Создание объекта ObjectDataSource с именем CategoriesDataSource
(щелкните для просмотра полноразмерного изображения)
Рис. 6. Настройка полей отображения и значений раскрывающегося списка (щелкните для просмотра полноразмерного изображения)
Повторите эту серию шагов, чтобы создать DropDownList для поставщиков. ID
Задайте для этого раскрывающегося списка значение Suppliers
и назовите его ObjectDataSource SuppliersDataSource
.
После добавления двух раскрывающихся списков добавьте Элемент 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" DataTextField="CompanyName"
DataSourceID="SuppliersDataSource"
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 void Products_EditCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property and rebind the data
Products.EditItemIndex = e.Item.ItemIndex;
Products.DataBind();
}
protected void Products_CancelCommand(object source, DataListCommandEventArgs e)
{
// Return to DataList to its pre-editing state
Products.EditItemIndex = -1;
Products.DataBind();
}
При использовании этих двух обработчиков событий при нажатии кнопки Изменить отображается интерфейс редактирования и нажатие кнопки Отмена возвращает измененный элемент в режим только для чтения. На рисунке 8 показан список данных после нажатия кнопки Изменить для Chef Антона с Gumbo Mix. Так как мы еще не добавили синтаксис привязки данных в интерфейс редактирования, ProductName
элемент TextBox пуст, Discontinued
флажок CheckBox снят, а первые элементы выбраны из Categories
и Suppliers
DropDownLists.
Рис. 8. Нажатие кнопки "Изменить" Отображает интерфейс редактирования (щелкните для просмотра полноразмерного изображения)
Шаг 4. Добавление синтаксиса DataBinding в интерфейс редактирования
Чтобы интерфейс редактирования отображал текущие значения продукта, необходимо использовать синтаксис привязки данных для назначения значений полей данных соответствующим значениям веб-элемента управления. Синтаксис привязки данных можно применить через Designer, перейдя на экран Изменение шаблонов и выбрав ссылку Изменить привязки данных в смарт-тегах веб-элементов управления. Кроме того, синтаксис привязки данных можно добавить непосредственно в декларативную разметку.
ProductName
Назначьте значение поля данных свойству ProductName
TextBox sText
, CategoryID
значения Categories
поля данных и SupplierID
— свойствам и Suppliers
DropDownListsSelectedValue
, а Discontinued
значение поля данных — свойству Discontinued
CheckBox sChecked
. После внесения этих изменений через Designer или напрямую через декларативную разметку, вернитесь на страницу через браузер и нажмите кнопку Изменить для Chef Антон с Gumbo Mix. Как показано на рисунке 9, синтаксис привязки данных добавил текущие значения в TextBox, DropDownLists и CheckBox.
Рис. 9. Нажатие кнопки "Изменить" Отображает интерфейс редактирования (щелкните для просмотра полноразмерного изображения)
Шаг 5. Сохранение изменений пользователя в обработчике событий UpdateCommand
Когда пользователь редактирует продукт и нажимает кнопку Обновить, происходит обратная передача и возникает событие DataList UpdateCommand
. В обработчике событий необходимо считывать значения из веб-элементов управления в интерфейсе EditItemTemplate
и BLL, чтобы обновить продукт в базе данных. Как мы видели в предыдущих руководствах, ProductID
обновленный продукт доступен через коллекцию DataKeys
. Доступ к введенным пользователем полям можно получить путем программной ссылки на веб-элементы управления с помощью FindControl("controlID")
, как показано в следующем коде:
protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
// Make sure the page is valid...
if (!Page.IsValid)
return;
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
// Read in the product name and price values
TextBox productName = (TextBox)e.Item.FindControl("ProductName");
DropDownList categories = (DropDownList)e.Item.FindControl("Categories");
DropDownList suppliers = (DropDownList)e.Item.FindControl("Suppliers");
CheckBox discontinued = (CheckBox)e.Item.FindControl("Discontinued");
string productNameValue = null;
if (productName.Text.Trim().Length > 0)
productNameValue = productName.Text.Trim();
int categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
bool discontinuedValue = discontinued.Checked;
// Call the ProductsBLL's UpdateProduct method...
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue,
discontinuedValue, productID);
// Revert the DataList back to its pre-editing state
Products.EditItemIndex = -1;
Products.DataBind();
}
Код начинается с проверки 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
. Я выбрал использовать значение (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
можно добавить в DropDownList с помощью Designer или непосредственно с помощью декларативного синтаксиса. При добавлении элемента DropDownList для представления значения базы данных NULL
обязательно добавьте ListItem
с помощью декларативного синтаксиса. Если вы используете ListItem
Редактор коллекции в 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
DropDownLists включают параметр (Нет) (щелкните для просмотра полноразмерного изображения)
Чтобы сохранить параметр (None) в качестве значения базы данных NULL
, необходимо вернуться к обработчику UpdateCommand
событий. Измените categoryIDValue
переменные и supplierIDValue
так, чтобы они были целыми числами, допускающим значение NULL, и присвойте им значение, отличное от Nothing
только в том случае, если список DropDownList SelectedValue
не является пустой строкой:
int? categoryIDValue = null;
if (!string.IsNullOrEmpty(categories.SelectedValue))
categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int? supplierIDValue = null;
if (!string.IsNullOrEmpty(suppliers.SelectedValue))
supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
При этом изменении значение будет передано Nothing
в UpdateProduct
метод BLL, если пользователь выбрал параметр (Нет) из одного из раскрывающихся списков, который соответствует значению 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 как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по