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


Обзор редактирования и удаления данных в DataList (C#)

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

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

Шаг 1. Создание веб-страниц редактирования и удаления учебников

Прежде чем начать изучение обновления и удаления данных из DataList, сначала рассмотрим, как создать страницы ASP.NET в нашем проекте веб-сайта, необходимые для этого руководства и следующих нескольких. Сначала добавьте новую папку с именем EditDeleteDataList. Затем добавьте в нее следующие ASP.NET страницы, чтобы связать каждую страницу с главной страницей Site.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 пользователем, перетащив его из Обозреватель решений в представление конструктора страницы.

Добавьте элемент управления user Control 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 указанным DataKeyField значением для каждого элемента DataList.DataKeys
  • Событие EditCommandзапускается при нажатии кнопки, LinkButton или ImageButton, свойство которого CommandName имеет значение Edit.
  • Событие CancelCommandзапускается при нажатии кнопки, LinkButton или ImageButton, свойство которого CommandName имеет значение Cancel.
  • Событие UpdateCommandзапускается при нажатии кнопки, LinkButton или ImageButton, свойство которого CommandName имеет значение Update.
  • Событие DeleteCommandзапускается при нажатии кнопки, 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. Чтобы включить поддержку удаления, в него ItemTemplateпотребуется еще один ObjectDataSource. Благодаря этому подходу эти внедренные объекты ObjectDataSource используются ControlParameters для декларативной привязки параметров ObjectDataSource к элементам управления входными данными пользователя (а не необходимости указывать их программным способом в обработчике событий DataList UpdateCommand ). Этот подход по-прежнему требует немного кода, который необходимо вызвать внедренные команды Update() ObjectDataSource, 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, не предназначен для вставки новых данных; Поэтому выберите параметр (Нет) в раскрывающемся списке на вкладке INSERT. Кроме того, выберите (Нет) для вкладок UPDATE и DELETE, так как обновления и удаления будут выполняться программным образом через BLL.

Убедитесь, что раскрывающиеся списки в вкладках ObjectDataSource insert, UPDATE и DELETE имеют значение (Нет)

Рис. 6. Убедитесь, что раскрывающиеся списки в вставке, обновлении и удалении вкладок ObjectDataSource имеют значение (Нет) (Щелкните, чтобы просмотреть изображение полного размера)

После настройки ObjectDataSource нажмите кнопку Готово, вернитесь в конструктор. Как мы видели в предыдущих примерах, при завершении конфигурации 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. Имена и цены продуктов отображаются в списке данных с двумя столбцами (щелкните, чтобы просмотреть изображение полного размера)

Примечание.

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

Средство чтения astute может вспомнить, что мы смогли отключить состояние представления при создании редактируемых GridViews, DetailsViews и FormViews. Это связано с тем, что ASP.NET веб-элементы управления 2.0 могут включать состояние управления, которое сохраняется в обратной связи, например состояние просмотра, но считается важным.

Отключение состояния представления в GridView просто пропускает тривиальные сведения о состоянии, но поддерживает состояние элемента управления (которое включает состояние, необходимое для редактирования и удаления). DataList, созданный в ASP.NET 1.x, не использует состояние управления и, следовательно, должен иметь состояние просмотра. Дополнительные сведения о назначении состояния элемента управления и его отличия от состояния представления см. в разделе "Состояние элемента управления" и "Состояние представления".

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

Элемент управления GridView состоит из коллекции полей (BoundFields, CheckBoxFields, TemplateFields и т. д.). Эти поля могут настраивать отрисованную разметку в зависимости от их режима. Например, если в режиме только для чтения значение поля данных отображается в виде текста; при редактировании он отрисовывает веб-элемент управления TextBox, свойство которого Text присваивается значению поля данных.

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

Его EditItemTemplate можно создать декларативно или с помощью конструктора (выбрав параметр "Изменить шаблоны" в смарт-теге DataList). Чтобы использовать параметр "Изменить шаблоны", сначала щелкните ссылку "Изменить шаблоны" в смарт-теге, а затем выберите EditItemTemplate элемент из раскрывающегося списка.

Согласитесь работать с DataList s EditItemTemplate

Рис. 8. Выбор работы с DataList (EditItemTemplateщелкните, чтобы просмотреть изображение полного размера)

Затем введите имя продукта и цену: и перетащите два элемента управления TextBox из панели элементов в EditItemTemplate интерфейс конструктора. Задайте свойства TextBoxes ID и ProductName UnitPrice.

Добавление текстового поля для имени и цены продукта

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

Необходимо привязать соответствующие значения поля данных продукта к Text свойствам двух текстовых полей. В смарт-тегах TextBoxes щелкните ссылку "Изменить DataBindings", а затем свяжите соответствующее поле данных со Text свойством, как показано на рис. 10.

Примечание.

При привязке UnitPrice поля данных к полю Price TextBox Text его можно отформатировать как значение валюты ({0:C}), общее число ({0:N}) или оставить его неформатируемым.

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

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

Обратите внимание, что диалоговое окно "Изменить dataBindings" на рис. 10 не включает флажок двусторонней привязки данных, который присутствует при редактировании TemplateField в GridView или DetailsView, или шаблона в FormView. Функция двусторонней привязки данных позволяет автоматически назначать значения входного веб-элемента управления для соответствующих объектов ObjectDataSource InsertParameters или UpdateParameters при вставке или обновлении данных. DataList не поддерживает двусторонняя привязка данных, как мы увидим далее в этом руководстве, после того как пользователь вносит изменения и готов к обновлению данных, нам потребуется программно получить доступ к этим свойствам TextBoxes Text и передать их значения соответствующему UpdateProduct методу в ProductsBLL классе.

Наконец, необходимо добавить кнопки "Обновить" и "Отмена" в кнопки EditItemTemplate. Как мы видели в руководстве master/Details Using a Bulleted List of Master Records with a Details DataList tutorial, when a Button, LinkButton или ImageButton, свойство которого CommandName задано в элементе Repeater или DataList, вызывается событие Repeater или DataList ItemCommand . Для DataList, если CommandName свойству присвоено определенное значение, также может возникать дополнительное событие. К специальным CommandName значениям свойств относятся, среди прочего:

  • Отмена CancelCommand вызывает событие
  • Изменение вызывает EditCommand событие
  • Обновление вызывает UpdateCommand событие

Имейте в виду, что эти события создаются в дополнение к событию ItemCommand .

Добавьте в EditItemTemplate два веб-элемента управления button, один из которых CommandName имеет значение Update, а другой — "Отмена". После добавления этих двух веб-элементов управления Button конструктор должен выглядеть следующим образом:

Снимок экрана: 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"Изменить" в конструктор или декларативно. Обязательно задайте для свойства кнопки CommandName "Изменить".

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

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

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

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

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

Так как событие 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. Сохранение изменений пользователя

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

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

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

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

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 обработчик событий. Этот обработчик событий должен:

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

Шаги 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 из коллекции. Затем эти два текстовых EditItemTemplate поля ссылаются и их Text свойства, хранящиеся в локальных переменных, productNameValue и unitPriceValue. Мы используем Decimal.Parse() метод для чтения значения из UnitPrice TextBox, чтобы, если введенное значение имеет символ валюты, оно по-прежнему может быть правильно преобразовано в Decimal значение.

Примечание.

Значения из ProductName UnitPrice текстовых ящиков назначаются только переменным productNameValue и unitPriceValue, если свойства TextBoxes Text имеют указанное значение. В противном случае для переменных используется значение Nothing , которое влияет на обновление данных со значением базы данных NULL . То есть наш код обрабатывает пустые строки в значения базы данных NULL , что является поведением интерфейса редактирования в элементах управления GridView, DetailsView и FormView.

После чтения значений ProductsBLL вызывается метод класса UpdateProduct , передавая имя продукта, цену и ProductID. Обработчик событий завершается, возвращая DataList в состояние предварительного редактирования, используя ту же логику, что и в обработчике CancelCommand событий.

EditCommandCancelCommandПосле завершения обработчиков UpdateCommand событий посетитель может изменить имя и цену продукта. На рисунках 14–16 показан этот рабочий процесс редактирования в действии.

При первом посещении страницы все продукты находятся в режиме только для чтения

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

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

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

После изменения значения нажмите кнопку

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

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

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

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

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

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

Добавьте кнопку "Удалить" рядом с кнопкой "Изменить" в параметре ItemTemplateCommandName "Удалить". После добавления этого элемента управления Button декларативный синтаксис DataList ItemTemplate должен выглядеть следующим образом:

<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 метода класса DeleteProduct .

После удаления продукта важно повторно привязать данные к DataList (DataList1.DataBind()), в противном случае DataList будет продолжать отображать продукт, который был только что удален.

Итоги

Хотя DataList не имеет точки и щелкает поддержку редактирования и удаления, которым пользуется GridView, с коротким фрагментом кода, его можно улучшить, чтобы включить эти функции. В этом руководстве мы узнали, как создать список продуктов с двумя столбцами, которые могут быть удалены, и имя и цена которых можно изменить. Добавление поддержки редактирования и удаления — это вопрос включения соответствующих веб-элементов управления в ItemTemplate и EditItemTemplateсоздания соответствующих обработчиков событий, чтения введенных пользователем и первичных значений ключей, а также взаимодействия с уровнем бизнес-логики.

Хотя мы добавили основные возможности редактирования и удаления в DataList, он не имеет более сложных функций. Например, проверка поля ввода отсутствует— если пользователь вводит цену слишком дорогой, исключение будет возникать Decimal.Parse при попытке преобразовать слишком дорого в .Decimal Аналогичным образом, если возникла проблема при обновлении данных на уровнях бизнес-логики или доступа к данным, пользователь будет представлен на стандартном экране ошибок. Без какого-либо подтверждения на кнопке "Удалить", случайно удаление продукта слишком вероятно.

В будущих руководствах мы посмотрим, как улучшить взаимодействие с пользователем.

Счастливое программирование!

Об авторе

Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 2.0 в 24 часах. Он может быть достигнут в mitchell@4GuysFromRolla.com. или через его блог, который можно найти на http://ScottOnWriting.NET.

Особое спасибо

Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты для этого руководства были Зак Джонс, Кен Песписа и Рэнди Шмидт. Хотите просмотреть мои предстоящие статьи MSDN? Если да, упадите меня линию в mitchell@4GuysFromRolla.com.