Общие сведения о редактировании и удалении данных в 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 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.

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

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

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

Настройка 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 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 значение 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 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 не 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 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 свойства хранятся в локальных переменных и 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 свойства значение Удалить. После добавления этого элемента управления 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.