Общие сведения об изменении и удалении данных в списке данных (VB)

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

Загрузить PDF-файл

Хотя в 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 включает свойства и события, не найденные в repeater, которые упрощают добавление таких возможностей. Поэтому в этом и последующих руководствах, посвященных редактированию и удалению, основное внимание уделяется только 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

Добавление страниц ASP.NET для учебников

Рис. 1. Добавление страниц ASP.NET для учебников

Как и в других папках, Default.aspx в папке EditDeleteDataList перечислены руководства в разделе . Помните, что SectionLevelTutorialListing.ascx пользовательский элемент управления предоставляет эту функцию. Поэтому добавьте этот пользовательский элемент управления в , Default.aspx перетащив его из Обозреватель решений в режим конструктора страницы.

Добавьте пользовательский элемент управления 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. Присвойте этому свойству поле первичного ключа отображаемых данных. Это приведет к заполнению коллекции DataList DataKeys указанным DataKeyField значением для каждого элемента DataList.
  • СобытиеEditCommand возникает при щелчке элемента Button, LinkButton или ImageButton, свойство которого CommandName имеет значение Изменить.
  • СобытиеCancelCommand возникает при щелчке элемента Button, LinkButton или ImageButton, свойство которого CommandName имеет значение Отмена.
  • СобытиеUpdateCommand возникает при щелчке элемента Button, LinkButton или ImageButton, свойство которого CommandName имеет значение Update.
  • СобытиеDeleteCommand возникает при щелчке элемента Button, LinkButton или ImageButton, свойство которого CommandName имеет значение Delete.

С помощью этих свойств и событий можно использовать четыре подхода, которые можно использовать для обновления и удаления данных из DataList:

  1. Используя методы ASP.NET 1.x , DataList существовал до ASP.NET 2.0 и ObjectDataSources и мог полностью обновлять и удалять данные программными средствами. Этот метод полностью отключает ObjectDataSource и требует привязки данных к DataList непосредственно из уровня бизнес-логики как при получении отображаемых данных, так и при обновлении или удалении записи.
  2. Использование элемента управления Single ObjectDataSource на странице для выбора, обновления и удаления, в то время как DataList не имеет встроенных возможностей редактирования и удаления GridView, нет причин, по которой мы не можем добавить их в себя. При таком подходе мы используем ObjectDataSource так же, как в примерах GridView, но должны создать обработчик событий для события DataList UpdateCommand , где мы задаем параметры ObjectDataSource и вызываем его Update() метод.
  3. При использовании элемента управления ObjectDataSource для выбора, но при обновлении и удалении напрямую в BLL при использовании варианта 2 необходимо написать фрагмент кода в событии UpdateCommand , назначить значения параметров и т. д. Вместо этого мы можем использовать ObjectDataSource для выбора, но выполнить обновление и удаление вызовов непосредственно к BLL (как в случае с вариантом 1). На мой взгляд, обновление данных путем прямого взаимодействия с BLL приводит к более удобочитаемому коду, чем назначение ObjectDataSource UpdateParameters и вызов его Update() метода.
  4. Использование декларативных средств с помощью нескольких объектов ObjectDataSources для трех предыдущих подходов требует немного кода. Если вы предпочитаете использовать как можно больше декларативного синтаксиса, последним вариантом является включение нескольких ObjectDataSources на страницу. Первый Объект ObjectDataSource извлекает данные из BLL и привязывает их к DataList. Для обновления добавляется другой объект ObjectDataSource, но добавляется непосредственно в dataList.EditItemTemplate Чтобы включить поддержку удаления, потребуется еще один ObjectDataSource в ItemTemplate. При таком подходе эти внедренные объекты ObjectDataSource используются для ControlParameters декларативной привязки параметров ObjectDataSource к пользовательским элементам управления ввода (вместо того, чтобы указывать их программным способом в обработчике событий DataList UpdateCommand ). Этот подход по-прежнему требует немного кода, необходимого для вызова внедренных команд 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.

Настройка ObjectDataSource для использования класса ProductsBLL

Рис. 4. Настройка ObjectDataSource для использования ProductsBLL класса (щелкните для просмотра полноразмерного изображения)

Возврат сведений о продукте с помощью метода GetProducts()

Рис. 5. Возврат сведений о продукте GetProducts() с помощью метода (щелкните для просмотра полноразмерного изображения)

DataList, как и GridView, не предназначен для вставки новых данных; Поэтому выберите параметр (Нет) в раскрывающемся списке на вкладке ВСТАВКА. Также выберите (Нет) для вкладок UPDATE и DELETE, так как обновления и удаления будут выполняться программным способом через BLL.

Убедитесь, что для Drop-Down Списки на вкладках INSERT, UPDATE и DELETE объектов ObjectDataSource задано значение (Нет)

Рис. 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 отображает название продукта и цену за единицу для каждого продукта в двух столбцах.

Названия и цены продуктов отображаются в списке данных Two-Column

Рис. 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 , а затем выберите элемент из раскрывающегося списка.

Выберите для работы с элементом 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}) или оставить его неформатированные.

Привязка полей данных ProductName и UnitPrice к свойствам текста textBoxes

Рис. 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 должны выглядеть примерно так:

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

Рис. 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 "Изменить" значение Изменить .

После добавления этой кнопки Изменить просмотрите страницу в браузере. С этим добавлением каждый список продуктов должен содержать кнопку Изменить.

Снимок экрана: DataList EditItemTemplate с добавленной кнопкой

Рис. 12. Добавление кнопок "Обновить" и "Отмена" в EditItemTemplate (щелкните для просмотра полноразмерного изображения)

Нажатие кнопки вызывает обратную передачу, но не переводит список продуктов в режим редактирования. Чтобы сделать продукт редактируемым, необходимо:

  1. Присвойте свойству DataList EditItemIndex значение индекса , DataListItem для которого была только что нажата кнопка "Изменить".
  2. Повторно привязывать данные к DataList. При повторной отрисовки DataList объект , DataListItem соответствующий ItemIndex dataList, EditItemIndex будет отображаться с помощью .EditItemTemplate

Так как событие DataList EditCommand возникает при нажатии кнопки Изменить, создайте EditCommand обработчик событий со следующим кодом:

Protected Sub DataList1_EditCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.EditCommand
    ' 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()
End Sub

Обработчик EditCommand событий передается в объект типа DataListCommandEventArgs в качестве второго входного параметра, который включает ссылку на DataListItem объект , для которого была нажата кнопка "Изменить" (e.Item). Обработчик событий сначала задает для dataList значение EditItemIndexItemIndex редактируемого DataListItem объекта , а затем повторно привязывает данные к DataList путем вызова метода DataList DataBind() .

После добавления этого обработчика событий вернитесь на страницу в браузере. Нажатие кнопки Изменить теперь делает продукт, который был нажат, редактируемым (см. рис. 13).

Нажатие кнопки

Рис. 13. Нажатие кнопки "Изменить" делает продукт редактируемым (щелкните для просмотра полноразмерного изображения)

Шаг 6. Сохранение изменений пользователя

На этом этапе нажатие кнопки "Обновить" или "Отмена" для измененного продукта не выполняет никаких действий; Чтобы добавить эту функцию, необходимо создать обработчики событий для событий DataList UpdateCommand и CancelCommand . Начните с создания обработчика CancelCommand событий, который будет выполняться при нажатии кнопки Отмена измененного продукта и возврате DataList в состояние предварительного редактирования.

Чтобы DataList отображал все свои элементы в режиме только для чтения, нам нужно:

  1. Присвойте свойству DataList EditItemIndex значение индекса несуществующего DataListItem индекса. -1 является безопасным выбором, так как DataListItem индексы начинаются с 0.
  2. Повторно привязывать данные к DataList. Так как никакие es не DataListItemItemIndex соответствуют значениям DataList EditItemIndex, весь список данных будет отображаться в режиме только для чтения.

Эти действия можно выполнить с помощью следующего кода обработчика событий:

Protected Sub DataList1_CancelCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.CancelCommand
    ' Set the DataList's EditItemIndex property to -1
    DataList1.EditItemIndex = -1
    ' Rebind the data to the DataList
    DataList1.DataBind()
End Sub

После этого нажатие кнопки Отмена возвращает dataList в состояние предварительного редактирования.

Последний обработчик событий, который нам нужно завершить, — это UpdateCommand обработчик событий. Этот обработчик событий должен:

  1. Программный доступ к имени и цене продукта, введенным пользователем, а также к измененным продуктам ProductID.
  2. Запустите процесс обновления, вызвав соответствующую UpdateProduct перегрузку ProductsBLL в классе .
  3. Присвойте свойству DataList EditItemIndex значение индекса несуществующего DataListItem индекса. -1 является безопасным выбором, так как DataListItem индексы начинаются с 0.
  4. Повторно привязывать данные к DataList. Так как никакие es не DataListItemItemIndex соответствуют значениям DataList EditItemIndex, весь список данных будет отображаться в режиме только для чтения.

Шаги 1 и 2 отвечают за сохранение изменений пользователя; Шаги 3 и 4 возвращают DataList в состояние предварительного редактирования после сохранения изменений и идентичны шагам, выполненным в обработчике CancelCommand событий.

Чтобы получить обновленное название продукта и цену, необходимо использовать FindControl метод для программной ссылки на веб-элементы управления TextBox в EditItemTemplate. Также необходимо получить измененное значение продукта ProductID . Когда мы изначально привязали ObjectDataSource к DataList, Visual Studio присвоил свойству DataList DataKeyField значение первичного ключа из источника данных (ProductID). Затем это значение можно получить из коллекции DataList DataKeys . Уделите некоторое время, чтобы убедиться, что свойству DataKeyField действительно присвоено значение ProductID.

В следующем коде реализованы четыре шага:

Protected Sub DataList1_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.UpdateCommand
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(DataList1.DataKeys(e.Item.ItemIndex))
    ' Read in the product name and price values
    Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
    Dim unitPrice As TextBox = CType(e.Item.FindControl("UnitPrice"), TextBox)
    Dim productNameValue As String = Nothing
    If productName.Text.Trim().Length > 0 Then
        productNameValue = productName.Text.Trim()
    End If
    Dim unitPriceValue As Nullable(Of Decimal) = Nothing
    If unitPrice.Text.Trim().Length > 0 Then
        unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(), NumberStyles.Currency)
    End If
    ' Call the ProductsBLL's UpdateProduct method...
    Dim productsAPI As New ProductsBLL()
    productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID)
    ' Revert the DataList back to its pre-editing state
    DataList1.EditItemIndex = -1
    DataList1.DataBind()
End Sub

Обработчик событий начинается с чтения измененных продуктов ProductID из DataKeys коллекции. Далее ссылаются на два элемента TextBox в EditItemTemplate , а их Text свойства хранятся в локальных переменных и productNameValueunitPriceValue. Мы используем 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 показан рабочий процесс редактирования в действии.

При первом посещении страницы все продукты находятся в режиме Read-Only

Рис. 14. При первом посещении страницы все продукты находятся в режиме Read-Only (щелкните для просмотра полноразмерного изображения)

Чтобы обновить название или цену продукта, нажмите кнопку Изменить.

Рис. 15. Чтобы обновить название или цену продукта, нажмите кнопку "Изменить" (щелкните для просмотра полноразмерного изображения)

После изменения значения нажмите кнопку Обновить, чтобы вернуться в режим Read-Only.

Рис. 16. После изменения значения нажмите кнопку Обновить, чтобы вернуться в режим Read-Only (щелкните для просмотра полноразмерного изображения)

Шаг 7. Добавление возможностей удаления

Действия по добавлению возможностей удаления в DataList аналогичны действиям по добавлению возможностей редактирования. Короче говоря, нам нужно добавить кнопку Удалить в ItemTemplate , которая при нажатии:

  1. Считывает данные в соответствующем продукте ProductID через коллекцию DataKeys .
  2. Выполняет удаление путем вызова ProductsBLL метода класса s DeleteProduct .
  3. Повторно привязывает данные к DataList.

Начнем с добавления кнопки Удалить в ItemTemplate.

При нажатии кнопки CommandName с параметрами "Изменить", "Обновить" или "Отмена" вызывается событие DataList ItemCommand вместе с дополнительным событием (например, при использовании команды Изменить EditCommand возникает событие). Аналогичным образом любой элемент Button, LinkButton или ImageButton в DataList, свойство которого CommandName имеет значение Delete, вызывает срабатывание DeleteCommand события (вместе с ItemCommand).

Добавьте кнопку Удалить рядом с кнопкой Изменить в ItemTemplate, установив для ее CommandName свойства значение Удалить. После добавления этого элемента управления Кнопка декларативный 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 Sub DataList1_DeleteCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.DeleteCommand
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(DataList1.DataKeys(e.Item.ItemIndex))
    ' Delete the data
    Dim productsAPI As New ProductsBLL()
    productsAPI.DeleteProduct(productID)
    ' Rebind the data to the DataList
    DataList1.DataBind()
End Sub

Нажатие кнопки Удалить вызывает обратную передачу и вызывает событие 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.