Общие сведения о редактировании и удалении данных в DataList (C#)
Хотя в DataList отсутствуют встроенные возможности редактирования и удаления, в этом руководстве мы рассмотрим, как создать DataList, поддерживающий редактирование и удаление базовых данных.
Введение
В учебнике Общие сведения о вставке, обновлении и удалении данных мы рассмотрели, как вставлять, обновлять и удалять данные с помощью архитектуры приложения, ObjectDataSource и элементов управления GridView, DetailsView и FormView. При использовании ObjectDataSource и этих трех веб-элементов управления данными реализация простых интерфейсов изменения данных была простой привязкой и включала простое закрепление флажка из смарт-тега. Не требуется писать код.
К сожалению, в DataList отсутствуют встроенные возможности редактирования и удаления, присущие элементу управления GridView. Эта недостающая функциональность отчасти связана с тем, что DataList является пережитком предыдущей версии ASP.NET, когда декларативные элементы управления источником данных и страницы изменения данных без кода были недоступны. Хотя DataList в ASP.NET 2.0 не предоставляет те же возможности изменения данных, что и GridView, мы можем использовать методы ASP.NET 1.x для включения таких функций. Этот подход требует немного кода, но, как мы увидим в этом руководстве, DataList имеет некоторые события и свойства, которые помогут в этом процессе.
В этом руководстве мы рассмотрим, как создать DataList, поддерживающий редактирование и удаление базовых данных. В будущих руководствах рассматриваются более сложные сценарии редактирования и удаления, включая проверку полей ввода, корректное обращение с исключениями, возникающими из уровней доступа к данным или бизнес-логики, и т. д.
Примечание
Как и DataList, элементу управления Repeater не хватает стандартной функции для вставки, обновления или удаления. Хотя такие функции можно добавить, DataList включает свойства и события, не найденные в ретрансляторе, которые упрощают добавление таких возможностей. Поэтому в этом и последующих руководствах, посвященных редактированию и удалению, основное внимание будет уделяться только DataList.
Шаг 1. Создание веб-страниц редактирования и удаления учебников
Прежде чем мы приступим к изучению того, как обновлять и удалять данные из DataList, давайте сначала уделим некоторое время созданию ASP.NET страниц в проекте веб-сайта, который нам понадобится для этого руководства и нескольких следующих. Начните с добавления новой папки с именем EditDeleteDataList
. Затем добавьте в папку следующие страницы ASP.NET, чтобы связать каждую страницу со страницей Site.master
master:
Default.aspx
Basics.aspx
BatchUpdate.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
Рис. 1. Добавление страниц ASP.NET для учебников
Как и в других папках, Default.aspx
в EditDeleteDataList
этой папке перечислены руководства в своем разделе. Помните, что SectionLevelTutorialListing.ascx
пользовательский элемент управления предоставляет эту функцию. Поэтому добавьте этот пользовательский элемент управления в , Default.aspx
перетащив его из Обозреватель решений в режим конструктора страницы.
Рис. 2. Добавление пользовательского SectionLevelTutorialListing.ascx
элемента управления в Default.aspx
(щелкните для просмотра полноразмерного изображения)
Наконец, добавьте страницы в виде записей в Web.sitemap
файл. В частности, добавьте следующую разметку после основных и подробных отчетов с помощью DataList и Repeater <siteMapNode>
:
<siteMapNode
title="Editing and Deleting with the DataList"
description="Samples of Reports that Provide Editing and Deleting Capabilities"
url="~/EditDeleteDataList/Default.aspx" >
<siteMapNode
title="Basics"
description="Examines the basics of editing and deleting with the
DataList control."
url="~/EditDeleteDataList/Basics.aspx" />
<siteMapNode
title="Batch Update"
description="Examines how to update multiple records at once in a
fully-editable DataList."
url="~/EditDeleteDataList/BatchUpdate.aspx" />
<siteMapNode
title="Error Handling"
description="Learn how to gracefully handle exceptions raised during the
data modification workflow."
url="~/EditDeleteDataList/ErrorHandling.aspx" />
<siteMapNode
title="Adding Data Entry Validation"
description="Help prevent data entry errors by providing validation."
url="~/EditDeleteDataList/UIValidation.aspx" />
<siteMapNode
title="Customize the User Interface"
description="Customize the editing user interfaces."
url="~/EditDeleteDataList/CustomizedUI.aspx" />
<siteMapNode
title="Optimistic Concurrency"
description="Learn how to help prevent simultaneous users from
overwritting one another s changes."
url="~/EditDeleteDataList/OptimisticConcurrency.aspx" />
<siteMapNode
title="Confirm On Delete"
description="Prompt a user for confirmation when deleting a record."
url="~/EditDeleteDataList/ConfirmationOnDelete.aspx" />
<siteMapNode
title="Limit Capabilities Based on User"
description="Learn how to limit the data modification functionality
based on the user s role or permissions."
url="~/EditDeleteDataList/UserLevelAccess.aspx" />
</siteMapNode>
После обновления Web.sitemap
просмотрите веб-сайт учебников через браузер. Меню слева теперь содержит элементы для учебников по редактированию и удалению DataList.
Рис. 3. Карта сайта теперь включает записи для учебников по редактированию и удалению DataList
Шаг 2. Изучение методов обновления и удаления данных
Редактирование и удаление данных с помощью GridView выполняется очень просто, так как под обложками GridView и ObjectDataSource работают согласованно. Как описано в учебнике Изучение событий, связанных с вставкой, обновлением и удалением , при нажатии кнопки Обновления строки Элемент GridView автоматически назначает свои поля, которые использовали двустороннюю привязку данных, коллекции UpdateParameters
ObjectDataSource, а затем вызывает этот метод ObjectDataSource Update()
.
К сожалению, DataList не предоставляет ни одной из этих встроенных функций. Мы обязаны гарантировать, что значения пользователя назначены параметрам ObjectDataSource и что вызывается его Update()
метод. Чтобы помочь нам в этом, DataList предоставляет следующие свойства и события:
- При
DataKeyField
обновлении или удалении свойства необходимо иметь возможность уникально идентифицировать каждый элемент в DataList. Задайте для этого свойства поле первичного ключа отображаемых данных. Это приведет к заполнению коллекции DataListDataKeys
указаннымDataKeyField
значением для каждого элемента DataList. - Событие
EditCommand
возникает при щелчке элемента Button, LinkButton или ImageButton, свойство которогоCommandName
имеет значение Изменить. - Событие
CancelCommand
возникает при щелчке элемента Button, LinkButton или ImageButton, для свойства которогоCommandName
задано значение Отмена. - Событие
UpdateCommand
возникает при щелчке элемента Button, LinkButton или ImageButton, для свойства которогоCommandName
задано значение Update. - Событие
DeleteCommand
возникает при щелчке элемента Button, LinkButton или ImageButton, для свойства которогоCommandName
задано значение Удалить.
С помощью этих свойств и событий можно использовать четыре подхода к обновлению и удалению данных из DataList:
- С помощью методов ASP.NET 1.x DataList существовал до ASP.NET 2.0 и ObjectDataSources и смог полностью обновлять и удалять данные с помощью программных средств. Этот метод полностью удаляет ObjectDataSource и требует привязки данных к DataList непосредственно из уровня бизнес-логики, как при получении отображаемых данных, так и при обновлении или удалении записи.
- Использование единого элемента управления ObjectDataSource на странице для выбора, обновления и удаления , в то время как DataList не имеет встроенных возможностей редактирования и удаления GridView, нет причин, по которой мы не можем добавить их в себя. При таком подходе мы используем ObjectDataSource так же, как в примерах GridView, но должны создать обработчик событий для события DataList
UpdateCommand
, где мы задаем параметры ObjectDataSource и вызываем егоUpdate()
метод. - При использовании элемента управления ObjectDataSource для выбора, но при обновлении и удалении непосредственно в BLL при использовании варианта 2 необходимо написать немного кода в событии
UpdateCommand
, назначить значения параметров и т. д. Вместо этого мы можем использовать ObjectDataSource для выбора, но выполнить обновление и удаление вызовов непосредственно в BLL (как в варианте 1). На мой взгляд, обновление данных путем взаимодействия непосредственно с BLL приводит к более удобочитаемому коду, чем назначение ObjectDataSourceUpdateParameters
и вызов егоUpdate()
метода. - Использование декларативных средств с помощью нескольких объектовDataSource в предыдущих трех подходах требует немного кода. Если вы предпочитаете использовать как можно больше декларативного синтаксиса, последний вариант — включить на страницу несколько ObjectDataSources. Первый объект ObjectDataSource извлекает данные из BLL и привязывает их к DataList. Для обновления добавляется еще один объект ObjectDataSource, но добавляется непосредственно в dataList.
EditItemTemplate
Чтобы включить поддержку удаления, потребуется еще один объект ObjectDataSource вItemTemplate
. При таком подходе эти внедренные объекты ObjectDataSource используются дляControlParameters
декларативной привязки параметров ObjectDataSource к пользовательским элементам управления ввода (вместо того, чтобы указывать их программным способом в обработчикеUpdateCommand
событий DataList). Этот подход по-прежнему требует немного кода, необходимого для вызова внедренных команд ObjectDataSource или ,Update()
Delete()
но требует гораздо меньше, чем при использовании трех других подходов. Недостатком здесь является то, что несколько ObjectDataSources загромождают страницу, что умаляет общую удобочитаемость.
Если вы вынуждены использовать только один из этих подходов, я бы выбрал вариант 1, так как он обеспечивает наибольшую гибкость и потому, что DataList изначально был разработан в соответствии с этим шаблоном. Хотя DataList был расширен для работы с элементами управления источником данных ASP.NET 2.0, он не имеет всех точек расширяемости или функций официальных веб-элементов управления данными ASP.NET 2.0 (GridView, DetailsView и FormView). Варианты с 2 по 4 не лишены достоинства, однако.
Это и будущие учебники по редактированию и удалению будут использовать ObjectDataSource для получения данных для отображения и прямых вызовов BLL для обновления и удаления данных (вариант 3).
Шаг 3. Добавление DataList и настройка его ObjectDataSource
В этом руководстве мы создадим dataList, который содержит сведения о продукте и предоставляет пользователю возможность изменить название и цену, а также полностью удалить продукт. В частности, мы извлекаем записи для отображения с помощью ObjectDataSource, но выполняем действия по обновлению и удалению, взаимодействуя напрямую с BLL. Прежде чем мы побеспокоимся о реализации возможностей редактирования и удаления в DataList, давайте сначала получим страницу для отображения продуктов в интерфейсе только для чтения. Так как мы изучили эти шаги в предыдущих руководствах, я быстро перейду к ним.
Начните с открытия Basics.aspx
страницы в папке EditDeleteDataList
и в режиме конструктора добавьте dataList на страницу. Затем из смарт-тега DataList создайте объект ObjectDataSource. Так как мы работаем с данными о продукте ProductsBLL
, настройте их для использования класса . Чтобы получить все продукты, выберите GetProducts()
метод на вкладке SELECT.
Рис. 4. Настройка ObjectDataSource для использования ProductsBLL
класса (щелкните для просмотра полноразмерного изображения)
Рис. 5. Возврат сведений о продукте GetProducts()
с помощью метода (щелкните для просмотра полноразмерного изображения)
DataList, как и GridView, не предназначен для вставки новых данных; Поэтому выберите параметр (Нет) в раскрывающемся списке на вкладке ВСТАВКА. Также выберите (Нет) для вкладок UPDATE и DELETE, так как обновления и удаления будут выполняться программным способом через BLL.
Рис. 6. Убедитесь, что для Drop-Down Списки на вкладках INSERT, UPDATE и DELETE объектов ObjectDataSource задано значение (нет) (щелкните для просмотра полноразмерного изображения)
После настройки ObjectDataSource нажмите кнопку Готово, вернувшись к Designer. Как мы уже видели в предыдущих примерах, при завершении настройки ObjectDataSource Visual Studio автоматически создает ItemTemplate
для DropDownList, отображая каждое из полей данных. Замените на ItemTemplate
тот, в котором отображаются только название и цена продукта. Кроме того, присвойте свойству RepeatColumns
значение 2.
Примечание
Как описано в руководстве Общие сведения о вставке, обновлении и удалении данных , при изменении данных с помощью ObjectDataSource в нашей архитектуре требуется удалить OldValuesParameterFormatString
свойство из декларативной разметки ObjectDataSource (или сбросить его значение по умолчанию, {0}
). Однако в этом руководстве мы используем ObjectDataSource только для получения данных. Поэтому нам не нужно изменять значение свойства ObjectDataSource OldValuesParameterFormatString
(хотя это не повредит).
После замены dataList ItemTemplate
по умолчанию на настроенный, декларативная разметка на странице должна выглядеть примерно так:
<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
DataSourceID="ObjectDataSource1" RepeatColumns="2">
<ItemTemplate>
<h5>
<asp:Label runat="server" ID="ProductNameLabel"
Text='<%# Eval("ProductName") %>'></asp:Label>
</h5>
Price: <asp:Label runat="server" ID="Label1"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
<br />
<br />
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
OldValuesParameterFormatString="original_{0}">
</asp:ObjectDataSource>
Уделите немного времени, чтобы просмотреть наш прогресс в браузере. Как показано на рисунке 7, DataList отображает название продукта и цену за единицу для каждого продукта в двух столбцах.
Рис. 7. Названия и цены продуктов отображаются в списке данных Two-Column (щелкните для просмотра полноразмерного изображения)
Примечание
DataList имеет ряд свойств, необходимых для процесса обновления и удаления, и эти значения хранятся в состоянии просмотра. Поэтому при создании DataList, поддерживающего редактирование или удаление данных, важно включить состояние представления DataList.
Проницательный читатель может вспомнить, что при создании редактируемых gridViews, DetailsViews и FormViews удалось отключить состояние представления. Это связано с тем, что веб-элементы управления ASP.NET 2.0 могут включать состояние элемента управления, которое сохраняется в обратной связи, например в состоянии представления, но считается важным.
Отключение состояния представления в GridView просто пропускает тривиальные сведения о состоянии, но сохраняет состояние элемента управления (которое включает состояние, необходимое для редактирования и удаления). DataList, созданный в ASP.NET 1.x, не использует состояние управления и, следовательно, должен иметь состояние просмотра. Дополнительные сведения о назначении состояния элемента управления и его отличиях от состояния представления см. в разделе Состояние элемента управления и состояние представления.
Шаг 4. Добавление пользовательского интерфейса редактирования
Элемент управления GridView состоит из коллекции полей (BoundFields, CheckBoxFields, TemplateFields и т. д.). Эти поля могут изменять отображаемые разметки в зависимости от режима. Например, в режиме только для чтения BoundField отображает значение поля данных в виде текста; В режиме редактирования он отображает веб-элемент управления TextBox, свойству которого Text
присваивается значение поля данных.
DataList, с другой стороны, отрисовывает свои элементы с помощью шаблонов. Элементы, доступные только для чтения, отрисовываются с помощью ItemTemplate
, а элементы в режиме редактирования — с помощью EditItemTemplate
. На этом этапе наш DataList имеет только ItemTemplate
. Для поддержки функций редактирования на уровне элемента необходимо добавить EditItemTemplate
объект , содержащий разметку, которая будет отображаться для редактируемого элемента. В этом руководстве мы будем использовать веб-элементы управления TextBox для изменения названия продукта и цены за единицу.
Можно EditItemTemplate
создать либо декларативно, либо с помощью Designer (выбрав параметр Изменить шаблоны из смарт-тега DataList). Чтобы использовать параметр Изменить шаблоны, сначала щелкните ссылку Изменить шаблоны в смарт-теге EditItemTemplate
, а затем выберите элемент из раскрывающегося списка.
Рис. 8. Выберите для работы с DataList EditItemTemplate
(Щелкните, чтобы просмотреть полноразмерное изображение)
Затем введите Product name: и Price: и перетащите два элемента управления TextBox из панели элементов в EditItemTemplate
интерфейс на Designer. Присвойте свойствам TextBoxes ID
значения ProductName
и UnitPrice
.
Рис. 9. Добавление текстового поля для названия и цены продукта (щелкните для просмотра полноразмерного изображения)
Необходимо привязать значения соответствующих полей данных продукта к Text
свойствам двух объектов TextBoxes. В смарт-тегах TextBoxes щелкните ссылку Изменить DataBindings и свяжите соответствующее поле данных со свойством Text
, как показано на рисунке 10.
Примечание
При привязке UnitPrice
поля данных к полю Price TextBox Text
можно отформатировать его как значение валюты ({0:C}
), общее число ({0:N}
) или оставить его неформатированные.
Рис. 10. Привязка ProductName
полей данных и UnitPrice
к Text
свойствам textBoxes
Обратите внимание, что диалоговое окно Изменение привязки данных на рис. 10 не содержит флажок Двусторонней привязки данных, который присутствует при редактировании TemplateField в GridView или DetailsView или шаблона в FormView. Функция двусторонней привязки данных позволяла автоматически назначать значение, введенное во входной веб-элемент управления, соответствующим objectDataSource InsertParameters
или UpdateParameters
при вставке или обновлении данных. DataList не поддерживает двусторонняя привязка данных, как мы увидим далее в этом руководстве. После внесения пользователем изменений и готовности к обновлению данных необходимо будет программно получить доступ к этим свойствам TextBoxes Text
и передать их значения в соответствующий UpdateProduct
метод в ProductsBLL
классе .
Наконец, необходимо добавить кнопки Обновить и Отмена в EditItemTemplate
. Как мы видели в руководстве по использованию маркированного списка главных записей с помощью DataList details , при щелчке элемента Button, LinkButton или ImageButton, свойство которого CommandName
задано, в repeater или DataList возникает событие Repeater или DataList ItemCommand
. Для DataList, если свойству CommandName
присвоено определенное значение, также может возникнуть дополнительное событие. К специальным CommandName
значениям свойств относятся, среди прочего:
- Отмена вызывает
CancelCommand
событие - Изменение вызывает
EditCommand
событие - Обновление вызывает
UpdateCommand
событие
Помните, что эти события вызываются в дополнение к событию ItemCommand
.
Добавьте к EditItemTemplate
двум элементам управления Button Web, для одного из которых CommandName
задано значение Обновить, а для другого — значение Отмена. После добавления этих двух веб-элементов управления Button Designer должны выглядеть примерно так:
Рис. 11. Добавление кнопок "Обновить" и "Отмена" в EditItemTemplate
(щелкните для просмотра полноразмерного изображения)
EditItemTemplate
После завершения декларативная разметка DataList должна выглядеть примерно так:
<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
DataSourceID="ObjectDataSource1" RepeatColumns="2">
<ItemTemplate>
<h5>
<asp:Label runat="server" ID="ProductNameLabel"
Text='<%# Eval("ProductName") %>' />
</h5>
Price: <asp:Label runat="server" ID="Label1"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
<br />
<br />
</ItemTemplate>
<EditItemTemplate>
Product name:
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Eval("ProductName") %>' /><br />
Price:
<asp:TextBox ID="UnitPrice" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>' /><br />
<br />
<asp:Button ID="UpdateProduct" runat="server"
CommandName="Update" Text="Update" />
<asp:Button ID="CancelUpdate" runat="server"
CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
</asp:DataList>
Шаг 5. Добавление сантехники в режим редактирования
На этом этапе у нашего DataList есть интерфейс редактирования, определенный через него EditItemTemplate
. Однако в настоящее время пользователь не может посетить нашу страницу, чтобы указать, что он хочет изменить сведения о продукте. Нам нужно добавить кнопку Изменить для каждого продукта, который при нажатии отображает этот элемент DataList в режиме редактирования. Начните с добавления кнопки Изменить в ItemTemplate
объект с помощью Designer или декларативно. Обязательно присвойте свойству кнопки CommandName
"Изменить" значение Изменить .
После добавления этой кнопки Изменить просмотрите страницу в браузере. С этим добавлением каждый список продуктов должен содержать кнопку Изменить.
Рис. 12. Добавление кнопок "Обновить" и "Отмена" в EditItemTemplate
(щелкните для просмотра полноразмерного изображения)
Нажатие кнопки вызывает обратную передачу, но не переводит список продуктов в режим редактирования. Чтобы сделать продукт редактируемым, необходимо:
- Присвойте свойству DataList
EditItemIndex
значение индекса ,DataListItem
для которого была только что нажата кнопка "Изменить". - Повторно привязывать данные к DataList. При повторной отрисовки DataList объект ,
DataListItem
соответствующийItemIndex
dataList,EditItemIndex
будет отображаться с помощью .EditItemTemplate
Так как событие DataList EditCommand
возникает при нажатии кнопки Изменить, создайте EditCommand
обработчик событий со следующим кодом:
protected void DataList1_EditCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property to the
// index of the DataListItem that was clicked
DataList1.EditItemIndex = e.Item.ItemIndex;
// Rebind the data to the DataList
DataList1.DataBind();
}
Обработчик EditCommand
событий передается в объект типа DataListCommandEventArgs
в качестве второго входного параметра, который включает ссылку на DataListItem
объект , для которого была нажата кнопка "Изменить" (e.Item
). Обработчик событий сначала задает для dataList значение EditItemIndex
ItemIndex
редактируемого DataListItem
объекта , а затем повторно привязывает данные к DataList путем вызова метода DataList DataBind()
.
После добавления этого обработчика событий вернитесь на страницу в браузере. Нажатие кнопки Изменить теперь делает продукт, который был нажат, редактируемым (см. рис. 13).
Рис. 13. Нажатие кнопки "Изменить" делает продукт редактируемым (щелкните для просмотра полноразмерного изображения)
Шаг 6. Сохранение изменений пользователя
На этом этапе нажатие кнопки "Обновить" или "Отмена" для измененного продукта не выполняет никаких действий; Чтобы добавить эту функцию, необходимо создать обработчики событий для событий DataList UpdateCommand
и CancelCommand
. Начните с создания обработчика CancelCommand
событий, который будет выполняться при нажатии кнопки Отмена измененного продукта и возврате DataList в состояние предварительного редактирования.
Чтобы DataList отображал все свои элементы в режиме только для чтения, нам нужно:
- Присвойте свойству DataList
EditItemIndex
значение индекса несуществующегоDataListItem
индекса.-1
является безопасным выбором, так какDataListItem
индексы начинаются с0
. - Повторно привязывать данные к DataList. Так как никакие es не
DataListItem
ItemIndex
соответствуют значениям DataListEditItemIndex
, весь список данных будет отображаться в режиме только для чтения.
Эти действия можно выполнить с помощью следующего кода обработчика событий:
protected void DataList1_CancelCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property to -1
DataList1.EditItemIndex = -1;
// Rebind the data to the DataList
DataList1.DataBind();
}
После этого нажатие кнопки Отмена возвращает dataList в состояние предварительного редактирования.
Последний обработчик событий, который нам нужно завершить, — это UpdateCommand
обработчик событий. Этот обработчик событий должен:
- Программный доступ к имени и цене продукта, введенным пользователем, а также к измененным продуктам
ProductID
. - Запустите процесс обновления, вызвав соответствующую
UpdateProduct
перегрузкуProductsBLL
в классе . - Присвойте свойству DataList
EditItemIndex
значение индекса несуществующегоDataListItem
индекса.-1
является безопасным выбором, так какDataListItem
индексы начинаются с0
. - Повторно привязывать данные к DataList. Так как никакие es не
DataListItem
ItemIndex
соответствуют значениям DataListEditItemIndex
, весь список данных будет отображаться в режиме только для чтения.
Шаги 1 и 2 отвечают за сохранение изменений пользователя; Шаги 3 и 4 возвращают DataList в состояние предварительного редактирования после сохранения изменений и идентичны шагам, выполненным в обработчике CancelCommand
событий.
Чтобы получить обновленное название продукта и цену, необходимо использовать FindControl
метод для программной ссылки на веб-элементы управления TextBox в EditItemTemplate
. Также необходимо получить измененное значение продукта ProductID
. Когда мы изначально привязали ObjectDataSource к DataList, Visual Studio присвоил свойству DataList DataKeyField
значение первичного ключа из источника данных (ProductID
). Затем это значение можно получить из коллекции DataList DataKeys
. Уделите некоторое время, чтобы убедиться, что свойству DataKeyField
действительно присвоено значение ProductID
.
В следующем коде реализованы четыре шага:
protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
{
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex]);
// Read in the product name and price values
TextBox productName = (TextBox)e.Item.FindControl("ProductName");
TextBox unitPrice = (TextBox)e.Item.FindControl("UnitPrice");
string productNameValue = null;
if (productName.Text.Trim().Length > 0)
productNameValue = productName.Text.Trim();
decimal? unitPriceValue = null;
if (unitPrice.Text.Trim().Length > 0)
unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(),
System.Globalization.NumberStyles.Currency);
// Call the ProductsBLL's UpdateProduct method...
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID);
// Revert the DataList back to its pre-editing state
DataList1.EditItemIndex = -1;
DataList1.DataBind();
}
Обработчик событий начинается с чтения измененных продуктов ProductID
из DataKeys
коллекции. Далее ссылаются на два элемента TextBox в EditItemTemplate
, а их Text
свойства хранятся в локальных переменных и productNameValue
unitPriceValue
. Мы используем Decimal.Parse()
метод для чтения значения из UnitPrice
TextBox, чтобы, если введенное значение содержит символ валюты, его все равно можно было правильно преобразовать в Decimal
значение.
Примечание
Значения из ProductName
и UnitPrice
TextBoxes назначаются переменным productNameValue и unitPriceValue только в том случае, если свойства TextBoxes Text имеют указанное значение. В противном случае для переменных используется значение Nothing
, которое приводит к обновлению данных значением базы данных NULL
. То есть наш код обрабатывает пустые строки в значения базы данных NULL
, что является поведением по умолчанию интерфейса редактирования в элементах управления GridView, DetailsView и FormView.
После считывания значений ProductsBLL
вызывается метод класса UpdateProduct
, передавая имя продукта, цену и ProductID
. Обработчик событий завершает работу, возвращая DataList в состояние предварительного редактирования, используя ту же логику, что и в обработчике CancelCommand
событий.
EditCommand
После завершения обработчиков событий , CancelCommand
и UpdateCommand
посетитель может изменить название и цену продукта. На рисунках 14-16 показан рабочий процесс редактирования в действии.
Рис. 14. При первом посещении страницы все продукты находятся в режиме Read-Only (щелкните для просмотра полноразмерного изображения)
Рис. 15. Чтобы обновить название или цену продукта, нажмите кнопку "Изменить" (нажмите для просмотра полноразмерного изображения)
Рис. 16. После изменения значения нажмите кнопку Обновить, чтобы вернуться в режим Read-Only (щелкните для просмотра полноразмерного изображения)
Шаг 7. Добавление возможностей удаления
Действия по добавлению возможностей удаления в DataList аналогичны действиям по добавлению возможностей редактирования. Короче говоря, нам нужно добавить кнопку Удалить в ItemTemplate
, которая при нажатии:
- Считывает соответствующие продукты
ProductID
через коллекциюDataKeys
. - Выполняет удаление путем вызова
ProductsBLL
метода класса sDeleteProduct
. - Повторно привязывает данные к DataList.
Начнем с добавления кнопки Удалить в ItemTemplate
.
При нажатии кнопки CommandName
с типом "Изменить", "Обновить" или "Отмена" возникает событие DataList ItemCommand
вместе с дополнительным событием (например, при использовании функции "Изменить EditCommand
" также возникает событие ). Аналогичным образом любой элемент Button, LinkButton или ImageButton в DataList, свойство которого CommandName
имеет значение Delete, вызывает DeleteCommand
событие (вместе с ItemCommand
).
Добавьте кнопку Удалить рядом с кнопкой Изменить в ItemTemplate
, установив для ее CommandName
свойства значение Удалить. После добавления этого элемента управления Button декларативный ItemTemplate
синтаксис DataList должен выглядеть следующим образом:
<ItemTemplate>
<h5>
<asp:Label runat="server" ID="ProductNameLabel"
Text='<%# Eval("ProductName") %>' />
</h5>
Price: <asp:Label runat="server" ID="Label1"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
<br />
<asp:Button runat="server" id="EditProduct" CommandName="Edit"
Text="Edit" />
<asp:Button runat="server" id="DeleteProduct" CommandName="Delete"
Text="Delete" />
<br />
<br />
</ItemTemplate>
Затем создайте обработчик событий для события DataList DeleteCommand
, используя следующий код:
protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
{
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex]);
// Delete the data
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.DeleteProduct(productID);
// Rebind the data to the DataList
DataList1.DataBind();
}
Нажатие кнопки Удалить вызывает обратную передачу данных и вызывает событие DataList DeleteCommand
. В обработчике событий доступ к значению продукта ProductID
, который был нажат, осуществляется из DataKeys
коллекции. Затем продукт удаляется путем вызова ProductsBLL
метода класса s DeleteProduct
.
После удаления продукта важно повторно привязать данные к DataList (DataList1.DataBind()
), в противном случае dataList будет по-прежнему отображать продукт, который был только что удален.
Сводка
Хотя в DataList отсутствует точка и поддержка редактирования и удаления, которой пользуется GridView, с коротким фрагментом кода его можно улучшить, чтобы включить эти функции. В этом руководстве мы узнали, как создать список продуктов, которые можно удалить из двух столбцов, а также имя и цену которых можно изменить. Добавление поддержки редактирования и удаления заключается в том, чтобы включить соответствующие веб-элементы управления в ItemTemplate
и EditItemTemplate
, создать соответствующие обработчики событий, считывать введенные пользователем значения и первичные ключи, а также взаимодействовать со слоем бизнес-логики.
Хотя мы добавили базовые возможности редактирования и удаления в DataList, в нем отсутствуют более сложные функции. Например, проверка поля ввода отсутствует. Если пользователь введет цену Слишком дорого, при попытке преобразовать слишком Decimal.Parse
дорогой в Decimal
значение будет создано исключение . Аналогичным образом, если возникает проблема с обновлением данных на уровнях бизнес-логики или доступа к данным, пользователю будет представлен стандартный экран ошибки. Без какого-либо подтверждения на кнопке Удалить случайное удаление продукта является слишком вероятным.
В будущих руководствах мы посмотрим, как улучшить взаимодействие с пользователем при редактировании.
Счастливое программирование!
Об авторе
Скотт Митчелл (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 как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по