Общие сведения о вставке, обновлении и удалении данных (C#)

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

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

В этом руководстве описано, как сопоставить методы Insert(), Update() и Delete() ObjectDataSource с методами классов BLL, а также как настроить элементы управления GridView, DetailsView и FormView для предоставления возможностей изменения данных.

Введение

В последних нескольких руководствах мы рассмотрели, как отображать данные на странице ASP.NET с помощью элементов управления GridView, DetailsView и FormView. Эти элементы управления просто работают с предоставленными им данными. Как правило, они управляют доступом к данным с помощью элемента управления источником данных, например ObjectDataSource. Мы узнали, как ObjectDataSource выступает в качестве прокси-сервера между страницей ASP.NET и базовыми данными. Когда GridView требуется отобразить данные, он вызывает метод ObjectDataSource Select() , который, в свою очередь, вызывает метод из нашего уровня бизнес-логики (BLL), который вызывает метод в соответствующем объекте TableAdapter уровня доступа к данным (DAL), который, в свою очередь, отправляет SELECT запрос в базу данных Northwind.

Помните, что при создании tableAdapters в DAL в нашем первом руководстве Visual Studio автоматически добавила методы для вставки, обновления и удаления данных из базовой таблицы базы данных. Кроме того, в разделе Создание уровня бизнес-логики мы разработали методы в BLL, которые вызвали эти методы DAL для изменения данных.

Помимо Select() метода ObjectDataSource также имеет Insert()методы , Update()и Delete() . Как и метод Select() , эти три метода можно сопоставить с методами в базовом объекте . При настройке для вставки, обновления или удаления данных элементы управления GridView, DetailsView и FormView предоставляют пользовательский интерфейс для изменения базовых данных. Этот пользовательский интерфейс вызывает Insert()методы , Update()и Delete() объекта ObjectDataSource, которые затем вызывают связанные методы базового объекта (см. рис. 1).

Методы Insert(), Update() и Delete() ObjectDataSource служат прокси-сервером в BLL.

Рис. 1. Методы , и Delete() ObjectDataSource Update()Insert()служат в качестве прокси-сервера в BLL (щелкните для просмотра полноразмерного изображения)

В этом руководстве мы покажем, как сопоставить методы ObjectDataSource Insert(), Update()и Delete() с методами классов в BLL, а также как настроить элементы управления GridView, DetailsView и FormView для предоставления возможностей изменения данных.

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

Прежде чем мы приступим к изучению вставки, обновления и удаления данных, давайте уделим некоторое время созданию ASP.NET страниц в проекте веб-сайта, которые потребуются для работы с этим руководством и несколькими последующими. Начните с добавления новой папки с именем EditInsertDelete. Затем добавьте в папку следующие страницы ASP.NET, чтобы связать каждую страницу со страницей Site.master master:

  • Default.aspx
  • Basics.aspx
  • DataModificationEvents.aspx
  • ErrorHandling.aspx
  • UIValidation.aspx
  • CustomizedUI.aspx
  • OptimisticConcurrency.aspx
  • ConfirmationOnDelete.aspx
  • UserLevelAccess.aspx

Добавление страниц ASP.NET для учебников по Modification-Related данных

Рис. 2. Добавление страниц ASP.NET для учебников по Modification-Related данных

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

Добавьте элемент управления SectionLevelTutorialListing.ascx в Default.aspx

Рис. 3. Добавление пользовательского SectionLevelTutorialListing.ascx элемента управления в Default.aspx (щелкните для просмотра полноразмерного изображения)

Наконец, добавьте страницы в виде записей в Web.sitemap файл. В частности, добавьте следующую разметку после настраиваемого форматирования <siteMapNode>:

<siteMapNode title="Editing, Inserting, and Deleting"
    url="~/EditInsertDelete/Default.aspx"
    description="Samples of Reports that Provide Editing, Inserting,
                  and Deleting Capabilities">
    <siteMapNode url="~/EditInsertDelete/Basics.aspx"
        title="Basics"
        description="Examines the basics of data modification with the
                      GridView, DetailsView, and FormView controls." />
    <siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx"
        title="Data Modification Events"
        description="Explores the events raised by the ObjectDataSource
                      pertinent to data modification." />
    <siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx"
        title="Error Handling"
        description="Learn how to gracefully handle exceptions raised
                      during the data modification workflow." />
    <siteMapNode url="~/EditInsertDelete/UIValidation.aspx"
        title="Adding Data Entry Validation"
        description="Help prevent data entry errors by providing validation." />
    <siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx"
        title="Customize the User Interface"
        description="Customize the editing and inserting user interfaces." />
    <siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx"
        title="Optimistic Concurrency"
        description="Learn how to help prevent simultaneous users from
                      overwritting one another s changes." />
    <siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx"
        title="Confirm On Delete"
        description="Prompt a user for confirmation when deleting a record." />
    <siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx"
        title="Limit Capabilities Based on User"
        description="Learn how to limit the data modification functionality
                      based on the user role or permissions." />
</siteMapNode>

После обновления Web.sitemapпросмотрите веб-сайт учебников через браузер. Меню слева теперь содержит элементы для редактирования, вставки и удаления учебников.

Карта сайта теперь включает записи для учебников по редактированию, вставке и удалению

Рис. 4. Карта сайта теперь включает записи для учебников по редактированию, вставке и удалению

Шаг 2. Добавление и настройка элемента управления ObjectDataSource

Так как GridView, DetailsView и FormView различаются по возможностям изменения данных и макету, давайте рассмотрим каждый из них по отдельности. Однако вместо того, чтобы каждый элемент управления использовал свой собственный ObjectDataSource, давайте просто создадим один объект ObjectDataSource, который могут совместно использовать все три примера элементов управления.

Откройте страницуBasics.aspx, перетащите объект ObjectDataSource из панели элементов в Designer и щелкните ссылку Настроить источник данных из смарт-тега. Так как является единственным классом ProductsBLL BLL, предоставляющим методы редактирования, вставки и удаления, настройте ObjectDataSource для использования этого класса.

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

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

На следующем экране можно указать, какие методы ProductsBLL класса сопоставляются с , , Update()и Delete() ObjectDataSourceSelect()Insert(), выбрав соответствующую вкладку и выбрав метод из раскрывающегося списка. Рисунок 6, который должен выглядеть уже знакомым, сопоставляет метод ObjectDataSource Select() с методом ProductsBLLGetProducts() класса . Методы Insert(), Update()и Delete() можно настроить, выбрав соответствующую вкладку в списке в верхней части.

Объект ObjectDataSource должен возвращать все продукты

Рис. 6. Функция ObjectDataSource возвращает все продукты (щелкните для просмотра полноразмерного изображения)

На рисунках 7, 8 и 9 показаны вкладки UPDATE, INSERT и DELETE объекта ObjectDataSource. Настройте эти вкладки таким образом, чтобы Insert()методы , Update()и Delete() вызвали ProductsBLL методы класса UpdateProduct, AddProductи DeleteProduct соответственно.

Сопоставьте метод Update() объекта ObjectDataSource с методом UpdateProduct класса ProductBLL

Рис. 7. Сопоставление метода ObjectDataSource Update() с методом ProductBLL класса UpdateProduct (щелкните для просмотра полноразмерного изображения)

Сопоставьте метод Insert() объекта ObjectDataSource с методом AddProduct класса ProductBLL

Рис. 8. Сопоставление метода ObjectDataSource Insert() с методом ProductBLL Add Product класса (щелкните для просмотра полноразмерного изображения)

Сопоставьте метод Delete() ObjectDataSource с методом DeleteProduct класса ProductBLL

Рис. 9. Сопоставление метода ObjectDataSource Delete() с методом ProductBLL класса DeleteProduct (щелкните для просмотра полноразмерного изображения)

Возможно, вы заметили, что эти методы уже выбраны в раскрывающихся списках на вкладках UPDATE, INSERT и DELETE. Это происходит благодаря нашему использованию DataObjectMethodAttribute , который украшает методы ProductsBLL. Например, метод DeleteProduct имеет следующую сигнатуру:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
    ...
}

Атрибут DataObjectMethodAttribute указывает назначение каждого метода для выбора, вставки, обновления или удаления и является ли он значением по умолчанию. Если вы опустили эти атрибуты при создании классов BLL, необходимо вручную выбрать методы на вкладках UPDATE, INSERT и DELETE.

Убедившись, что соответствующие ProductsBLL методы сопоставлены с методами ObjectDataSource Insert(), Update()и Delete() , нажмите кнопку Готово, чтобы завершить работу мастера.

Изучение разметки ObjectDataSource

После настройки ObjectDataSource с помощью мастера перейдите в представление Источник, чтобы изучить созданную декларативную разметку. Тег <asp:ObjectDataSource> указывает базовый объект и методы для вызова. Кроме того, существуют , и , которые сопоставляются DeleteParametersс входным параметрами ProductsBLL для методов класса AddProduct, UpdateProductи DeleteProduct :InsertParametersUpdateParameters

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <DeleteParameters>
        <asp:Parameter Name="productID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
    </InsertParameters>
</asp:ObjectDataSource>

ObjectDataSource включает параметр для каждого из входных параметров связанных с ним методов так же, как и список SelectParameter , когда ObjectDataSource настроен на вызов метода select, который ожидает входной параметр (например GetProductsByCategoryID(categoryID), ). Как мы увидим вкратце, значения для этих DeleteParameters, UpdateParametersи InsertParameters задаются автоматически GridView, DetailsView и FormView перед вызовом метода ObjectDataSource Insert(), Update()или Delete() . Эти значения также можно задать программным способом, как мы рассмотрим в следующем руководстве.

Одним из побочных эффектов использования мастера для настройки ObjectDataSource является то, что Visual Studio задает свойству OldValuesParameterFormatString значениеoriginal_{0}. Это значение свойства используется для включения исходных значений редактируемых данных и полезно в двух сценариях:

  • Если при редактировании записи пользователи могут изменить значение первичного ключа. В этом случае необходимо предоставить как новое значение первичного ключа, так и исходное значение первичного ключа, чтобы можно было найти запись с исходным значением первичного ключа и соответствующим образом обновить ее значение.
  • При использовании оптимистического параллелизма. Оптимистичный параллелизм — это метод, гарантирующий, что два одновременных пользователя не перезаписывают изменения друг друга, и является темой для будущего руководства.

Свойство OldValuesParameterFormatString указывает имя входных параметров в методах обновления и удаления базового объекта для исходных значений. Мы рассмотрим это свойство и его назначение более подробно при изучении оптимистичного параллелизма. Я возвращаю его сейчас, однако, потому что наши методы BLL не ожидают исходных значений, и поэтому важно, чтобы мы удалили это свойство. Если OldValuesParameterFormatString для свойства задано значение, отличное от значения по умолчанию ({0}), при попытке веб-элемента управления данными вызвать методы или Delete() ObjectDataSource Update() будет возникать ошибка, так как ObjectDataSource попытается передать как указанные илиDeleteParameters, так UpdateParameters и исходные параметры значения.

Если это не совсем ясно на данном этапе, не беспокойтесь, мы рассмотрим это свойство и его полезность в будущем руководстве. На данный момент необходимо либо полностью удалить это объявление свойства из декларативного синтаксиса, либо задать значение по умолчанию ({0}).

Примечание

Если просто очистить OldValuesParameterFormatString значение свойства из окно свойств в представлении конструктора, свойство по-прежнему будет существовать в декларативном синтаксисе, но будет иметь пустую строку. Это, к сожалению, по-прежнему приведет к той же проблеме, о которой говорилось выше. Поэтому либо полностью удалите свойство из декларативного синтаксиса, либо в окно свойств задайте значение по умолчанию , {0}.

Шаг 3. Добавление веб-элемента управления "Данные" и его настройка для изменения данных

После добавления ObjectDataSource на страницу и настройки мы готовы добавить веб-элементы управления данными на страницу, чтобы отобразить данные и предоставить пользователю средства для их изменения. Мы рассмотрим GridView, DetailsView и FormView отдельно, так как эти веб-элементы управления данными отличаются возможностями изменения данных и конфигурацией.

Как мы увидим в оставшейся части этой статьи, добавить простую поддержку редактирования, вставки и удаления с помощью элементов управления GridView, DetailsView и FormView на самом деле так же просто, как проверить несколько флажков. В реальном мире существует множество тонкостей и пограничных вариантов, которые делают предоставление таких функций более задействованным, чем просто наведите указатель и щелчок. Однако в этом руководстве основное внимание уделяется исключительно упрощению возможностей изменения данных. В будущих руководствах будут рассмотрены проблемы, которые, несомненно, возникнут в реальной обстановке.

Удаление данных из GridView

Начните с перетаскивания GridView из панели элементов на Designer. Затем привяжите ObjectDataSource к GridView, выбрав его из раскрывающегося списка в смарт-теге GridView. На этом этапе декларативная разметка GridView будет:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID"
            InsertVisible="False"
            ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName"
            SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
           SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
           SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit"
           HeaderText="QuantityPerUnit"
           SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
           SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
           HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder"
           HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel"
           HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued"
           HeaderText="Discontinued" SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName"
           HeaderText="CategoryName" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
            HeaderText="SupplierName" ReadOnly="True"
            SortExpression="SupplierName" />
    </Columns>
</asp:GridView>

Привязка GridView к ObjectDataSource с помощью смарт-тега имеет два преимущества:

  • BoundFields и CheckBoxFields создаются автоматически для каждого поля, возвращаемого ObjectDataSource. Кроме того, свойства BoundField и CheckBoxField задаются на основе метаданных базового поля. Например, поля , CategoryNameи SupplierName помечаются ProductIDкак доступные только для чтения в ProductsDataTable и поэтому не должны обновляться при редактировании. Для этого свойствам BoundFields ReadOnly присваивается значение true.
  • Свойство DataKeyNames назначается полям первичного ключа базового объекта. Это важно при использовании GridView для редактирования или удаления данных, так как это свойство указывает поле (или набор полей), которое уникальным образом идентифицирует каждую запись. Дополнительные сведения о свойстве см. в DataKeyNames учебнике Master/Detail Using a Selectable Master GridView with a Details DetailView ( Использование выбранного элемента управления GridView с подробным представлением сведений ).

Хотя GridView можно привязать к ObjectDataSource с помощью окно свойств или декларативного синтаксиса, для этого необходимо вручную добавить соответствующие BoundField и DataKeyNames разметку.

Элемент управления GridView обеспечивает встроенную поддержку редактирования и удаления на уровне строк. При настройке GridView для поддержки удаления добавляется столбец кнопок "Удалить". Когда пользователь нажимает кнопку Удалить для определенной строки, происходит обратная связь и GridView выполняет следующие действия.

  1. Присваиваются значения ObjectDataSource DeleteParameters .
  2. Вызывается метод ObjectDataSource Delete() , который удаляет указанную запись.
  3. GridView повторно привязывает себя к ObjectDataSource путем вызова его Select() метода.

Значения, присвоенные объекту DeleteParameters , являются значениями DataKeyNames полей для строки, для которой была нажата кнопка Удалить. Поэтому очень важно правильно задать свойство GridView DataKeyNames . Если он отсутствует, DeleteParameters будет присвоено null значение на шаге 1, что, в свою очередь, не приведет к удалению записей на шаге 2.

Примечание

Коллекция DataKeys хранится в состоянии элемента управления GridView, то DataKeys есть значения будут запоминаться при обратной отправке, даже если состояние представления GridView было отключено. Однако очень важно, чтобы состояние представления оставалось включенным для GridViews, поддерживающих редактирование или удаление (поведение по умолчанию). Если для свойства GridView задано EnableViewState значение false, поведение редактирования и удаления будет работать нормально для одного пользователя, но если есть одновременные пользователи, удаляющие данные, существует вероятность того, что эти параллельные пользователи могут случайно удалить или изменить записи, которые они не намеревались.

Это же предупреждение также относится к DetailsView и FormView.

Чтобы добавить возможности удаления в GridView, просто перейдите к его смарт-тегу и проверка флажок Включить удаление.

Установите флажок Включить удаление

Рис. 10. Установите флажок Включить удаление

Если установить флажок Включить удаление из смарт-тега, в GridView добавляется commandField. CommandField отображает столбец в GridView с кнопками для выполнения одной или нескольких из следующих задач: выбор записи, редактирование и удаление записи. Ранее мы видели commandField в действии с выделением записей в учебнике Master/Detail Using a Selectable Master GridView with a DetailsView .

CommandField содержит ряд свойств, указывающих ShowXButton , какие ряды кнопок отображаются в CommandField. Установив флажок Включить удаление, в коллекцию Столбцы GridView было добавлено CommandField, свойство которого ShowDeleteButton имеет значение true .

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

На этом этапе мы готовы добавить поддержку удаления в GridView. Как показано на рисунке 11, при посещении этой страницы через браузер присутствует столбец кнопок Удалить.

CommandField добавляет столбец кнопок удаления

Рис. 11. CommandField добавляет столбец кнопок удаления (щелкните для просмотра полноразмерного изображения)

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

Примечание

Если вы используете скачивание, сопровождающее это руководство, эти проблемы уже были учтены. Тем не менее, я призываю вас прочитать сведения, перечисленные ниже, чтобы помочь определить проблемы, которые могут возникнуть, и подходящие обходные пути.

Если при попытке удалить продукт вы получаете исключение, похожее на сообщение "ObjectDataSource "ObjectDataSource1" не удалось найти неуниверсивный метод DeleteProduct с параметрами: productID, original_ProductID", скорее всего, вы забыли удалить OldValuesParameterFormatString свойство из ObjectDataSource. С указанным свойством OldValuesParameterFormatString ObjectDataSource пытается передать методу DeleteProduct входные productID параметры и original_ProductID . DeleteProductОднако принимает только один входной параметр, отсюда и исключение. При удалении OldValuesParameterFormatString свойства (или присвоении ему значения {0}) ОбъектDataSource не будет пытаться передать исходный входной параметр.

Убедитесь, что свойство OldValuesParameterFormatString удалено.

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

Даже если вы удалили OldValuesParameterFormatString свойство, при попытке удалить продукт с сообщением "Инструкция DELETE конфликтует с ограничением REFERENCE "FK_Order_Details_Products". База данных Northwind содержит ограничение внешнего ключа между таблицей Order Details и Products , что означает, что продукт нельзя удалить из системы, если в Order Details таблице есть одна или несколько записей для него. Так как каждый продукт в базе данных Northwind имеет по крайней мере одну запись в Order Details, мы не можем удалить какие-либо продукты до тех пор, пока мы не удалим связанные с ним записи о заказах.

Ограничение внешнего ключа запрещает удаление продуктов

Рис. 13. Ограничение внешнего ключа запрещает удаление продуктов (щелкните для просмотра полноразмерного изображения)

В нашем руководстве мы просто удалим все записи из Order Details таблицы. В реальном приложении необходимо выполнить одно из следующих действий:

  • Другой экран для управления сведениями о заказе
  • Расширение метода для DeleteProduct включения логики удаления сведений о заказе указанного продукта
  • Измените SQL-запрос, используемый TableAdapter, чтобы включить удаление сведений о заказе указанного продукта.

Давайте просто удалим все записи из таблицы, Order Details чтобы обойти ограничение внешнего ключа. Перейдите к Обозреватель сервера в Visual Studio, щелкните правой NORTHWND.MDF кнопкой мыши узел и выберите Создать запрос. Затем в окне запроса выполните следующую инструкцию SQL: DELETE FROM [Order Details]

Удаление всех записей из таблицы сведений о заказах

Рис. 14. Удаление всех записей из Order Details таблицы (щелкните для просмотра полноразмерного изображения)

После очистки Order Details таблицы нажатие кнопки Удалить приведет к удалению продукта без ошибок. Если при нажатии кнопки Удалить продукт не удаляется, проверка убедитесь, что свойству GridView DataKeyNames задано поле первичного ключа (ProductID).

Примечание

При нажатии кнопки Удалить происходит обратная связь и запись удаляется. Это может быть опасно, так как можно легко случайно нажать кнопку Удалить в неправильной строке. В следующем руководстве мы посмотрим, как добавить подтверждение на стороне клиента при удалении записи.

Изменение данных с помощью GridView

Наряду с удалением элемент управления GridView также обеспечивает встроенную поддержку редактирования на уровне строк. При настройке GridView для поддержки редактирования добавляется столбец кнопок Изменить. С точки зрения конечного пользователя нажатие кнопки "Изменить" строки приводит к тому, что строка становится редактируемой, превратив ячейки в текстовые поля, содержащие существующие значения, и заменив кнопку Изменить кнопкой Обновить и Отмена. После внесения необходимых изменений пользователь может нажать кнопку Обновить, чтобы зафиксировать изменения, или кнопку Отмена, чтобы отменить их. В любом случае после нажатия кнопки Обновить или Отмена GridView возвращается в состояние предварительного редактирования.

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

  1. Свойство GridView присваивается индексу строки, для которой была нажата EditItemIndex кнопка "Изменить".
  2. GridView повторно привязывает себя к ObjectDataSource путем вызова его Select() метода.
  3. Индекс строки, соответствующий , EditItemIndex отображается в режиме редактирования. В этом режиме кнопка Изменить заменяется кнопками Обновить и Отмена, а BoundFields ReadOnly со свойствами False (по умолчанию) отображаются как веб-элементы управления TextBox, свойства которых Text назначены значениям полей данных.

На этом этапе разметка возвращается в браузер, что позволяет конечному пользователю вносить любые изменения в данные строки. Когда пользователь нажимает кнопку Обновить, происходит обратная связь, а GridView выполняет следующие действия:

  1. Значениям ObjectDataSource UpdateParameters назначаются значения, введенные конечным пользователем в интерфейсе редактирования GridView.
  2. Вызывается метод ObjectDataSource Update() , обновляя указанную запись.
  3. GridView повторно привязывает себя к ObjectDataSource путем вызова его Select() метода.

Значения первичного ключа, назначенные на шаге UpdateParameters 1, поступают из значений, указанных в DataKeyNames свойстве , тогда как значения, не являющиеся первичными ключами, — из текста в веб-элементах управления TextBox для редактируемой строки. Как и при удалении, очень важно правильно задать свойство GridView DataKeyNames . Если он отсутствует, значение первичного UpdateParameters ключа будет присвоено null на шаге 1, что, в свою очередь, не приведет к обновлению записей на шаге 2.

Функцию редактирования можно активировать, просто установив флажок Включить редактирование в смарт-теге GridView.

Установите флажок Включить редактирование

Рис. 15. Установите флажок Включить редактирование

Установите флажок Включить редактирование, чтобы добавить CommandField (при необходимости) и задать для его ShowEditButton свойства значение true. Как мы видели ранее, CommandField содержит ряд свойств, указывающих ShowXButton , какие ряды кнопок отображаются в CommandField. Если установить флажок Включить редактирование, ShowEditButton свойство добавляется в существующий CommandField:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True"
            ShowEditButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

Это все, что нужно для добавления зачаточной поддержки редактирования. Как показано на рисунке 16, интерфейс редактирования довольно сырой, каждый BoundField, свойству которого ReadOnly задано значение false (по умолчанию), отображается как TextBox. Сюда входят такие поля, как CategoryID и SupplierID, которые являются ключами к другим таблицам.

Нажатие кнопки редактирования Chais Отображает строку в режиме редактирования

Рис. 16. Нажатие кнопки редактирования chai отображает строку в режиме редактирования (щелкните для просмотра полноразмерного изображения)

Помимо запроса пользователей на изменение значений внешнего ключа напрямую, интерфейс интерфейса редактирования отсутствует следующими способами:

  • Если пользователь вводит CategoryID или SupplierID , которые не существуют в базе данных, UPDATE объект будет нарушать ограничение внешнего ключа, вызывая исключение.
  • Интерфейс редактирования не включает проверку. Если не указать обязательное значение (например ProductName, ) или ввести строковое значение, в котором ожидается числовое значение (например, в текстовое поле "Слишком много!" UnitPrice ), возникнет исключение. В будущем учебнике будет рассмотрено, как добавить элементы управления проверкой в пользовательский интерфейс редактирования.
  • В настоящее время все поля продуктов, не доступные только для чтения, должны быть включены в GridView. Если бы мы удалили поле из GridView, например UnitPrice, при обновлении данных GridView не установит UnitPriceUpdateParameters значение, что приведет к изменению записи UnitPrice базы данных на NULL значение. Аналогичным образом, если обязательное поле, например ProductName, удаляется из GridView, обновление завершится ошибкой с тем же исключением "Столбец "ProductName" не допускает значений NULL, упомянутых выше.
  • Форматирование интерфейса редактирования оставляет желать лучшего. Отображается с четырьмя десятичными UnitPrice точками. В идеале CategoryID значения и SupplierID будут содержать раскрывающиеся списки, которые перечисляют категории и поставщики в системе.

Это все недостатки, с которыми нам придется жить сейчас, но они будут рассмотрены в будущих руководствах.

Вставка, изменение и удаление данных с помощью DetailsView

Как мы видели в предыдущих руководствах, элемент управления DetailsView отображает по одной записи за раз и, как и GridView, позволяет редактировать и удалять отображаемую в данный момент запись. Интерфейс конечного пользователя с редактированием и удалением элементов из DetailsView и рабочий процесс со стороны ASP.NET идентичен интерфейсу GridView. DetailsView отличается от GridView тем, что он также предоставляет встроенную поддержку вставки.

Чтобы продемонстрировать возможности изменения данных GridView, сначала добавьте DetailsView на страницу Basics.aspx над существующим Элементом GridView и привяжите его к существующему Объекту ObjectDataSource с помощью смарт-тега DetailsView. Затем очистите свойства DetailsView Height и Width проверка параметр Включить разбиение по страницам из смарт-тега. Чтобы включить поддержку редактирования, вставки и удаления, просто проверка флажки Включить редактирование, Включить вставку и Включить удаление в смарт-теге.

Снимок экрана: окно

Рис. 17. Настройка DetailsView для поддержки редактирования, вставки и удаления

Как и в случае с GridView, добавление правки, вставки или удаления добавляет CommandField в DetailsView, как показано в следующем декларативном синтаксисе:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
    <Fields>
        <asp:BoundField DataField="ProductID"
            HeaderText="ProductID" InsertVisible="False"
            ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName"
            HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
            SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit"
            HeaderText="QuantityPerUnit"
            SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice"
            HeaderText="UnitPrice" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
            HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder"
            HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel"
            HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued"
            HeaderText="Discontinued" SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName"
            HeaderText="CategoryName" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
            HeaderText="SupplierName" ReadOnly="True"
            SortExpression="SupplierName" />
        <asp:CommandField ShowDeleteButton="True"
            ShowEditButton="True" ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

Обратите внимание, что для DetailsView commandField по умолчанию отображается в конце коллекции Columns. Так как поля DetailsView отображаются в виде строк, CommandField отображается в виде строки с кнопками Вставка, Изменить и Удалить в нижней части DetailsView.

Снимок экрана: DetailsView с командным полем в нижней строке с кнопками Вставка, Изменить и Удалить.

Рис. 18. Настройка DetailsView для поддержки редактирования, вставки и удаления (щелкните для просмотра полноразмерного изображения)

Нажатие кнопки Удалить запускает ту же последовательность событий, что и в GridView: обратная связь; затем DetailsView заполняет объект ObjectDataSource DeleteParameters на DataKeyNames основе значений и завершается вызовом метода ObjectDataSource Delete() , который фактически удаляет продукт из базы данных. Редактирование в DetailsView также работает так же, как в GridView.

Для вставки пользователю отображается кнопка Создать, которая при нажатии отображает DetailsView в режиме вставки. В режиме вставки кнопка Создать заменяется кнопками Вставка и Отмена, и отображаются только те Поля BoundField, для которых InsertVisible задано значение true (по умолчанию). Для этих полей данных, определенных как поля с автоматическим приращением, например ProductID, свойство InsertVisible имеет значение false при привязке DetailsView к источнику данных с помощью смарт-тега.

При привязке источника данных к DetailsView с помощью смарт-тега Visual Studio задает свойству InsertVisiblefalse значение только для полей с автоматическим приращением. Поля только для чтения, такие как CategoryName и SupplierName, будут отображаться в пользовательском интерфейсе "режим вставки", если их InsertVisible свойству явно не присвоено значение false. Уделите некоторое время, чтобы задать для этих двух полей InsertVisible свойства falseс помощью декларативного синтаксиса DetailsView или ссылки Изменить поля в смарт-теге. На рисунке 19 показано, как задать InsertVisible для свойств значение false , щелкнув ссылку Изменить поля.

Снимок экрана: окно

Рис. 19. Northwind Traders Now Предлагает Чай Acme (Щелкните, чтобы просмотреть изображение в полном размере)

После настройки InsertVisible свойств просмотрите страницу Basics.aspx в браузере и нажмите кнопку Создать. На рисунке 20 показан элемент DetailsView при добавлении нового напитка Acme Tea в нашу линейку продуктов.

Снимок экрана: представление DetailsView страницы Basics.aspx в веб-браузере.

Рис. 20. Northwind Traders Now Предлагает Чай Acme (Щелкните, чтобы просмотреть изображение в полном размере)

После ввода сведений для acme Tea и нажатия кнопки Вставка происходит обратная связь, и новая запись добавляется в таблицу Products базы данных. Так как в этом представлении DetailsView перечислены продукты по порядку, с которым они существуют в таблице базы данных, мы должны перестраивать страницу до последнего продукта, чтобы увидеть новый продукт.

Сведения о чае Acme

Рис. 21. Сведения о чае Acme (щелкните для просмотра полноразмерного изображения)

Примечание

Свойство CurrentMode DetailsView указывает на отображаемый интерфейс и может иметь одно из следующих значений: Edit, Insertили ReadOnly. Свойство DefaultMode указывает режим, в который возвращается DetailsView после завершения редактирования или вставки, и полезно для отображения DetailsView, который постоянно находится в режиме редактирования или вставки.

Возможности вставки и редактирования элемента DetailsView имеют те же ограничения, что и GridView: пользователь должен вводить существующие CategoryID значения и SupplierID через текстовое поле; в интерфейсе отсутствует логика проверки; все поля продукта, которые не допускают NULL значения или не имеют значения по умолчанию, указанные на уровне базы данных, должны быть включены в интерфейс вставки. и так далее.

Методы, которые мы рассмотрим для расширения и улучшения интерфейса редактирования GridView в будущих статьях, можно также применить к интерфейсам редактирования и вставки элемента управления DetailsView.

Использование FormView для более гибкого пользовательского интерфейса изменения данных

FormView предлагает встроенную поддержку вставки, редактирования и удаления данных, но так как он использует шаблоны вместо полей, нет места для добавления BoundFields или CommandField, используемых элементами управления GridView и DetailsView для предоставления интерфейса изменения данных. Вместо этого интерфейс веб-элементов управления для сбора пользовательских данных при добавлении нового элемента или редактировании существующего вместе с кнопками Создать, Изменить, Удалить, Вставка, Обновить и Отмена необходимо добавить вручную в соответствующие шаблоны. К счастью, Visual Studio автоматически создаст необходимый интерфейс при привязке FormView к источнику данных с помощью раскрывающегося списка в смарт-теге.

Чтобы проиллюстрировать эти методы, начните с добавления FormView на Basics.aspx страницу и из смарт-тега FormView привяжите его к уже созданному объекту ObjectDataSource. Это приведет к созданию EditItemTemplateэлементов управления , InsertItemTemplateи ItemTemplate для FormView с веб-элементами управления TextBox для сбора входных данных пользователя и веб-элементов управления Кнопка для кнопок Создать, Изменить, Удалить, Вставка, Обновить и Отмена. Кроме того, свойству FormView DataKeyNames присваивается поле первичного ключа (ProductID) объекта, возвращаемого ObjectDataSource. Наконец, проверка параметр Включить разбиение по страницам в смарт-теге FormView.

Ниже показана декларативная разметка ItemTemplate для FormView после привязки FormView к ObjectDataSource. По умолчанию каждое поле продукта, отличное от логического значения, привязано к свойству Text веб-элемента управления Label, а каждое поле логического значения (Discontinued) — к свойству Checked отключенного веб-элемента управления CheckBox. Чтобы кнопки Создать, Изменить и Удалить запускали определенное поведение FormView при нажатии, крайне важно, чтобы Newих CommandName значения были равны , Editи Deleteсоответственно.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ...
    </EditItemTemplate>
    <InsertItemTemplate>
        ...
    </InsertItemTemplate>
    <ItemTemplate>
        ProductID:
        <asp:Label ID="ProductIDLabel" runat="server"
            Text='<%# Eval("ProductID") %>'></asp:Label><br />
        ProductName:
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Bind("ProductName") %>'>
        </asp:Label><br />
        SupplierID:
        <asp:Label ID="SupplierIDLabel" runat="server"
            Text='<%# Bind("SupplierID") %>'>
        </asp:Label><br />
        CategoryID:
        <asp:Label ID="CategoryIDLabel" runat="server"
            Text='<%# Bind("CategoryID") %>'>
        </asp:Label><br />
        QuantityPerUnit:
        <asp:Label ID="QuantityPerUnitLabel" runat="server"
            Text='<%# Bind("QuantityPerUnit") %>'>
        </asp:Label><br />
        UnitPrice:
        <asp:Label ID="UnitPriceLabel" runat="server"
            Text='<%# Bind("UnitPrice") %>'></asp:Label><br />
        UnitsInStock:
        <asp:Label ID="UnitsInStockLabel" runat="server"
            Text='<%# Bind("UnitsInStock") %>'>
        </asp:Label><br />
        UnitsOnOrder:
        <asp:Label ID="UnitsOnOrderLabel" runat="server"
            Text='<%# Bind("UnitsOnOrder") %>'>
        </asp:Label><br />
        ReorderLevel:
        <asp:Label ID="ReorderLevelLabel" runat="server"
            Text='<%# Bind("ReorderLevel") %>'>
        </asp:Label><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
            Checked='<%# Bind("Discontinued") %>'
            Enabled="false" /><br />
        CategoryName:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Bind("CategoryName") %>'>
        </asp:Label><br />
        SupplierName:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Bind("SupplierName") %>'>
        </asp:Label><br />
        <asp:LinkButton ID="EditButton" runat="server"
            CausesValidation="False" CommandName="Edit"
            Text="Edit">
        </asp:LinkButton>
        <asp:LinkButton ID="DeleteButton" runat="server"
            CausesValidation="False" CommandName="Delete"
            Text="Delete">
        </asp:LinkButton>
        <asp:LinkButton ID="NewButton" runat="server"
            CausesValidation="False" CommandName="New"
            Text="New">
        </asp:LinkButton>
    </ItemTemplate>
</asp:FormView>

На рисунке 22 показаны элементы FormView ItemTemplate при просмотре в браузере. В нижней части каждого поля продукта отображаются кнопки Создать, Изменить и Удалить.

Defaut FormView ItemTemplate Списки поле

Рис. 22. Представление defaut FormView ItemTemplate Списки поля "Каждый продукт" вместе с кнопками "Создать", "Изменить" и "Удалить" (щелкните для просмотра полноразмерного изображения)

Как и в случае с GridView и DetailsView, нажатие кнопки Удалить или любой кнопки, LinkButton или ImageButton, свойство которого CommandName имеет значение Delete, вызывает обратную передачу, заполняет объект ObjectDataSource DeleteParameters на основе значения FormView DataKeyNames и вызывает метод ObjectDataSource Delete() .

При нажатии кнопки Изменить происходит обратная передача и данные отскокируются в EditItemTemplate, который отвечает за отрисовку интерфейса редактирования. Этот интерфейс включает веб-элементы управления для редактирования данных, а также кнопки Обновить и Отмена. По умолчанию EditItemTemplate , создаваемый Visual Studio, содержит метку для всех полей с автоматическим приращением (ProductID), элемент TextBox для каждого поля, отличного от логических значений, и CheckBox для каждого поля логического значения. Это поведение очень похоже на автоматически созданные Поля BoundField в элементах управления GridView и DetailsView.

Примечание

Одна небольшая проблема с автоматическим созданием FormView заключается в EditItemTemplate том, что он отображает веб-элементы управления TextBox для тех полей, которые доступны только для чтения, таких как CategoryName и SupplierName. В ближайшее время мы посмотрим, как это сделать.

Элементы управления TextBox в EditItemTemplate привязываются Text к значению соответствующего поля данных с помощью двусторонней привязки данных. Двусторонняя привязка данных, обозначенная параметром <%# Bind("dataField") %>, выполняет привязку данных как при привязке данных к шаблону, так и при заполнении параметров ObjectDataSource для вставки или редактирования записей. То есть, когда пользователь нажимает кнопку Изменить из ItemTemplate, Bind() метод возвращает указанное значение поля данных. После того как пользователь вновит изменения и нажмет кнопку Обновить, опубликованные значения, соответствующие полям данных, указанным с помощью Bind() , применяются к объекту ObjectDataSource UpdateParameters. Кроме того, односторонняя привязка данных, обозначенная параметром <%# Eval("dataField") %>, извлекает значения полей данных только при привязке данных к шаблону и не возвращает введенные пользователем значения в параметры источника данных при обратной отправке.

В следующей декларативной разметке показан элемент FormView EditItemTemplate. Обратите внимание, что Bind() метод используется в синтаксисе привязки данных и что веб-элементы управления "Обновить" и "Отмена кнопки" имеют соответствующие CommandName свойства.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ProductID:
        <asp:Label ID="ProductIDLabel1" runat="server"
          Text="<%# Eval("ProductID") %>"></asp:Label><br />
        ProductName:
        <asp:TextBox ID="ProductNameTextBox" runat="server"
          Text="<%# Bind("ProductName") %>">
        </asp:TextBox><br />
        SupplierID:
        <asp:TextBox ID="SupplierIDTextBox" runat="server"
          Text="<%# Bind("SupplierID") %>">
        </asp:TextBox><br />
        CategoryID:
        <asp:TextBox ID="CategoryIDTextBox" runat="server"
          Text="<%# Bind("CategoryID") %>">
        </asp:TextBox><br />
        QuantityPerUnit:
        <asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
           Text="<%# Bind("QuantityPerUnit") %>">
        </asp:TextBox><br />
        UnitPrice:
        <asp:TextBox ID="UnitPriceTextBox" runat="server"
           Text="<%# Bind("UnitPrice") %>">
        </asp:TextBox><br />
        UnitsInStock:
        <asp:TextBox ID="UnitsInStockTextBox" runat="server"
           Text="<%# Bind("UnitsInStock") %>">
        </asp:TextBox><br />
        UnitsOnOrder:
        <asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
           Text="<%# Bind("UnitsOnOrder") %>">
        </asp:TextBox><br />
        ReorderLevel:
        <asp:TextBox ID="ReorderLevelTextBox" runat="server"
           Text="<%# Bind("ReorderLevel") %>">
        </asp:TextBox><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
            Checked="<%# Bind("Discontinued") %>" /><br />
        CategoryName:
        <asp:TextBox ID="CategoryNameTextBox" runat="server"
             Text="<%# Bind("CategoryName") %>">
        </asp:TextBox><br />
        SupplierName:
        <asp:TextBox ID="SupplierNameTextBox" runat="server"
             Text="<%# Bind("SupplierName") %>">
        </asp:TextBox><br />
        <asp:LinkButton ID="UpdateButton" runat="server"
            CausesValidation="True" CommandName="Update"
            Text="Update">
        </asp:LinkButton>
        <asp:LinkButton ID="UpdateCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel"
            Text="Cancel">
        </asp:LinkButton>
    </EditItemTemplate>
    <InsertItemTemplate>
        ...
    </InsertItemTemplate>
    <ItemTemplate>
        ...
    </ItemTemplate>
</asp:FormView>

На EditItemTemplateэтом этапе мы создадим исключение, если мы попытаемся его использовать. Проблема заключается в CategoryName том, что поля и SupplierName отображаются как веб-элементы управления TextBox в EditItemTemplate. Нам нужно либо изменить эти текстовые поля на Метки, либо удалить их полностью. Давайте просто полностью удалите их из EditItemTemplate.

На рисунке 23 показан элемент FormView в браузере после нажатия кнопки Изменить для Chai. Обратите внимание, SupplierName что поля и CategoryName , отображаемые в , ItemTemplate больше не присутствуют, так как мы только что удалили их из EditItemTemplate. При нажатии кнопки Обновить FormView выполняет те же действия, что и элементы управления GridView и DetailsView.

По умолчанию элемент EditItemTemplate отображает каждое редактируемое поле продукта в виде элемента TextBox или CheckBox

Рис. 23. По умолчанию EditItemTemplate отображается каждое редактируемое поле продукта в виде текстового поля или флажка (щелкните для просмотра полноразмерного изображения)

При нажатии кнопки Вставка происходит обратная связь FormView ItemTemplate . Однако данные не привязаны к FormView, так как добавляется новая запись. Интерфейс InsertItemTemplate включает веб-элементы управления для добавления новой записи вместе с кнопками Вставка и Отмена. По умолчанию InsertItemTemplate , создаваемый Visual Studio, содержит элемент TextBox для каждого поля, отличного от логического значения, и CheckBox для каждого поля логического значения, аналогично интерфейсу автоматически созданного EditItemTemplate. Свойство элемента управления TextBox привязано Text к значению соответствующего поля данных с помощью двусторонней привязки данных.

В следующей декларативной разметке показан элемент FormView InsertItemTemplate. Обратите внимание, что Bind() метод используется в синтаксисе привязки данных и что веб-элементы управления "Вставка" и "Отмена кнопки" имеют соответствующие CommandName свойства.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ...
    </EditItemTemplate>
    <InsertItemTemplate>
        ProductName:
        <asp:TextBox ID="ProductNameTextBox" runat="server"
           Text="<%# Bind("ProductName") %>">
        </asp:TextBox><br />
        SupplierID:
        <asp:TextBox ID="SupplierIDTextBox" runat="server"
           Text="<%# Bind("SupplierID") %>">
        </asp:TextBox><br />
        CategoryID:
        <asp:TextBox ID="CategoryIDTextBox" runat="server"
           Text="<%# Bind("CategoryID") %>">
        </asp:TextBox><br />
        QuantityPerUnit:
        <asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
           Text="<%# Bind("QuantityPerUnit") %>">
        </asp:TextBox><br />
        UnitPrice:
        <asp:TextBox ID="UnitPriceTextBox" runat="server"
           Text="<%# Bind("UnitPrice") %>">
        </asp:TextBox><br />
        UnitsInStock:
        <asp:TextBox ID="UnitsInStockTextBox" runat="server"
           Text="<%# Bind("UnitsInStock") %>">
        </asp:TextBox><br />
        UnitsOnOrder:
        <asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
           Text="<%# Bind("UnitsOnOrder") %>">
        </asp:TextBox><br />
        ReorderLevel:
        <asp:TextBox ID="ReorderLevelTextBox" runat="server"
           Text="<%# Bind("ReorderLevel") %>">
        </asp:TextBox><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
           Checked="<%# Bind("Discontinued") %>" /><br />
        CategoryName:
        <asp:TextBox ID="CategoryNameTextBox" runat="server"
            Text="<%# Bind("CategoryName") %>">
        </asp:TextBox><br />
        SupplierName:
        <asp:TextBox ID="SupplierNameTextBox" runat="server"
           Text="<%# Bind("SupplierName") %>">
        </asp:TextBox><br />
        <asp:LinkButton ID="InsertButton" runat="server"
            CausesValidation="True" CommandName="Insert"
            Text="Insert">
        </asp:LinkButton>
        <asp:LinkButton ID="InsertCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel"
            Text="Cancel">
        </asp:LinkButton>
    </InsertItemTemplate>
    <ItemTemplate>
        ...
    </ItemTemplate>
</asp:FormView>

Существует тонкость автоматического создания InsertItemTemplateFormView . В частности, веб-элементы управления TextBox создаются даже для тех полей, которые доступны только для чтения, таких как CategoryName и SupplierName. Как и в EditItemTemplateслучае с , необходимо удалить эти поля TextBox из InsertItemTemplate.

На рисунке 24 показан элемент FormView в браузере при добавлении нового продукта Acme Coffee. Обратите внимание, что SupplierName поля и CategoryName , отображаемые в , ItemTemplate больше не присутствуют, так как мы только что удалили их. При нажатии кнопки Вставка FormView выполняет те же действия, что и элемент управления DetailsView, добавляя новую запись в таблицу Products . На рисунке 25 показаны сведения о продукте Acme Coffee в FormView после его вставки.

InsertItemTemplate диктует интерфейс вставки FormView

Рис. 24. Диктует InsertItemTemplate интерфейс вставки FormView (щелкните для просмотра полноразмерного изображения)

Сведения о новом продукте Acme Coffee отображаются в FormView.

Рис. 25. Сведения о новом продукте Acme Coffee отображаются в FormView (щелкните для просмотра полноразмерного изображения)

Разделяя интерфейсы только для чтения, редактирования и вставки в три отдельных шаблона, FormView обеспечивает более точное управление этими интерфейсами, чем DetailsView и GridView.

Примечание

Как и DetailsView, свойство FormView CurrentMode указывает на отображаемый интерфейс, а его DefaultMode свойство указывает режим, в который FormView возвращается после завершения редактирования или вставки.

Сводка

В этом руководстве мы рассмотрели основы вставки, редактирования и удаления данных с помощью GridView, DetailsView и FormView. Все три этих элемента управления предоставляют некоторый уровень встроенных возможностей изменения данных, которые можно использовать без написания ни одной строки кода на странице ASP.NET благодаря элементам управления Data Web и ObjectDataSource. Тем не менее, простые методы и методы щелчка делают довольно слабым и наивным пользовательским интерфейсом изменения данных. Для проверки, внедрения программных значений, корректной обработки исключений, настройки пользовательского интерфейса и т. д. нам потребуется использовать набор методов, которые будут рассмотрены в следующих нескольких руководствах.

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

Об авторе

Скотт Митчелл( Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Он может быть доступен в mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.