Общие сведения о вставке, обновлении и удалении данных (C#)
В этом руководстве описано, как сопоставить методы 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).
Рис. 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
Рис. 2. Добавление страниц ASP.NET для учебников по Modification-Related данных
Как и в других папках, Default.aspx
в папке EditInsertDelete
будут перечислены учебники в своем разделе. Помните, что 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 для использования этого класса.
Рис. 5. Настройка ObjectDataSource для использования ProductsBLL
класса (щелкните для просмотра полноразмерного изображения)
На следующем экране можно указать, какие методы ProductsBLL
класса сопоставляются с , , Update()
и Delete()
ObjectDataSourceSelect()
Insert()
, выбрав соответствующую вкладку и выбрав метод из раскрывающегося списка. Рисунок 6, который должен выглядеть уже знакомым, сопоставляет метод ObjectDataSource Select()
с методом ProductsBLL
GetProducts()
класса . Методы Insert()
, Update()
и Delete()
можно настроить, выбрав соответствующую вкладку в списке в верхней части.
Рис. 6. Функция ObjectDataSource возвращает все продукты (щелкните для просмотра полноразмерного изображения)
На рисунках 7, 8 и 9 показаны вкладки UPDATE, INSERT и DELETE объекта ObjectDataSource. Настройте эти вкладки таким образом, чтобы Insert()
методы , Update()
и Delete()
вызвали ProductsBLL
методы класса UpdateProduct
, AddProduct
и DeleteProduct
соответственно.
Рис. 7. Сопоставление метода ObjectDataSource Update()
с методом ProductBLL
класса UpdateProduct
(щелкните для просмотра полноразмерного изображения)
Рис. 8. Сопоставление метода ObjectDataSource Insert()
с методом ProductBLL
Add Product
класса (щелкните для просмотра полноразмерного изображения)
Рис. 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
:InsertParameters
UpdateParameters
<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 выполняет следующие действия.
- Присваиваются значения ObjectDataSource
DeleteParameters
. - Вызывается метод ObjectDataSource
Delete()
, который удаляет указанную запись. - 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, при посещении этой страницы через браузер присутствует столбец кнопок Удалить.
Рис. 11. CommandField добавляет столбец кнопок удаления (щелкните для просмотра полноразмерного изображения)
Если вы самостоятельно создаете это руководство, при тестировании этой страницы при нажатии кнопки Удалить возникнет исключение. Продолжайте чтение, чтобы узнать, почему были вызваны эти исключения и как их исправить.
Примечание
Если вы используете скачивание, сопровождающее это руководство, эти проблемы уже были учтены. Тем не менее, я призываю вас прочитать сведения, перечисленные ниже, чтобы помочь определить проблемы, которые могут возникнуть, и подходящие обходные пути.
Если при попытке удалить продукт вы получаете исключение, похожее на сообщение "ObjectDataSource "ObjectDataSource1" не удалось найти неуниверсивный метод DeleteProduct с параметрами: productID, original_ProductID", скорее всего, вы забыли удалить OldValuesParameterFormatString
свойство из ObjectDataSource. С указанным свойством OldValuesParameterFormatString
ObjectDataSource пытается передать методу DeleteProduct
входные productID
параметры и original_ProductID
. DeleteProduct
Однако принимает только один входной параметр, отсюда и исключение. При удалении OldValuesParameterFormatString
свойства (или присвоении ему значения {0}
) ОбъектDataSource не будет пытаться передать исходный входной параметр.
Рис. 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 выполняет следующие действия:
- Свойство GridView присваивается индексу строки, для которой была нажата
EditItemIndex
кнопка "Изменить". - GridView повторно привязывает себя к ObjectDataSource путем вызова его
Select()
метода. - Индекс строки, соответствующий ,
EditItemIndex
отображается в режиме редактирования. В этом режиме кнопка Изменить заменяется кнопками Обновить и Отмена, а BoundFieldsReadOnly
со свойствами False (по умолчанию) отображаются как веб-элементы управления TextBox, свойства которыхText
назначены значениям полей данных.
На этом этапе разметка возвращается в браузер, что позволяет конечному пользователю вносить любые изменения в данные строки. Когда пользователь нажимает кнопку Обновить, происходит обратная связь, а GridView выполняет следующие действия:
- Значениям ObjectDataSource
UpdateParameters
назначаются значения, введенные конечным пользователем в интерфейсе редактирования GridView. - Вызывается метод ObjectDataSource
Update()
, обновляя указанную запись. - 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
, которые являются ключами к другим таблицам.
Рис. 16. Нажатие кнопки редактирования chai отображает строку в режиме редактирования (щелкните для просмотра полноразмерного изображения)
Помимо запроса пользователей на изменение значений внешнего ключа напрямую, интерфейс интерфейса редактирования отсутствует следующими способами:
- Если пользователь вводит
CategoryID
илиSupplierID
, которые не существуют в базе данных,UPDATE
объект будет нарушать ограничение внешнего ключа, вызывая исключение. - Интерфейс редактирования не включает проверку. Если не указать обязательное значение (например
ProductName
, ) или ввести строковое значение, в котором ожидается числовое значение (например, в текстовое поле "Слишком много!"UnitPrice
), возникнет исключение. В будущем учебнике будет рассмотрено, как добавить элементы управления проверкой в пользовательский интерфейс редактирования. - В настоящее время все поля продуктов, не доступные только для чтения, должны быть включены в GridView. Если бы мы удалили поле из GridView, например
UnitPrice
, при обновлении данных GridView не установитUnitPrice
UpdateParameters
значение, что приведет к изменению записи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.
Рис. 18. Настройка DetailsView для поддержки редактирования, вставки и удаления (щелкните для просмотра полноразмерного изображения)
Нажатие кнопки Удалить запускает ту же последовательность событий, что и в GridView: обратная связь; затем DetailsView заполняет объект ObjectDataSource DeleteParameters
на DataKeyNames
основе значений и завершается вызовом метода ObjectDataSource Delete()
, который фактически удаляет продукт из базы данных. Редактирование в DetailsView также работает так же, как в GridView.
Для вставки пользователю отображается кнопка Создать, которая при нажатии отображает DetailsView в режиме вставки. В режиме вставки кнопка Создать заменяется кнопками Вставка и Отмена, и отображаются только те Поля BoundField, для которых InsertVisible
задано значение true
(по умолчанию). Для этих полей данных, определенных как поля с автоматическим приращением, например ProductID
, свойство InsertVisible имеет значение false
при привязке DetailsView к источнику данных с помощью смарт-тега.
При привязке источника данных к DetailsView с помощью смарт-тега Visual Studio задает свойству InsertVisible
false
значение только для полей с автоматическим приращением. Поля только для чтения, такие как CategoryName
и SupplierName
, будут отображаться в пользовательском интерфейсе "режим вставки", если их InsertVisible
свойству явно не присвоено значение false
. Уделите некоторое время, чтобы задать для этих двух полей InsertVisible
свойства false
с помощью декларативного синтаксиса DetailsView или ссылки Изменить поля в смарт-теге. На рисунке 19 показано, как задать InsertVisible
для свойств значение false
, щелкнув ссылку Изменить поля.
Рис. 19. Northwind Traders Now Предлагает Чай Acme (Щелкните, чтобы просмотреть изображение в полном размере)
После настройки InsertVisible
свойств просмотрите страницу Basics.aspx
в браузере и нажмите кнопку Создать. На рисунке 20 показан элемент DetailsView при добавлении нового напитка Acme Tea в нашу линейку продуктов.
Рис. 20. Northwind Traders Now Предлагает Чай Acme (Щелкните, чтобы просмотреть изображение в полном размере)
После ввода сведений для acme Tea и нажатия кнопки Вставка происходит обратная связь, и новая запись добавляется в таблицу Products
базы данных. Так как в этом представлении DetailsView перечислены продукты по порядку, с которым они существуют в таблице базы данных, мы должны перестраивать страницу до последнего продукта, чтобы увидеть новый продукт.
Рис. 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
при просмотре в браузере. В нижней части каждого поля продукта отображаются кнопки Создать, Изменить и Удалить.
Рис. 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.
Рис. 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>
Существует тонкость автоматического создания InsertItemTemplate
FormView . В частности, веб-элементы управления TextBox создаются даже для тех полей, которые доступны только для чтения, таких как CategoryName
и SupplierName
. Как и в EditItemTemplate
случае с , необходимо удалить эти поля TextBox из InsertItemTemplate
.
На рисунке 24 показан элемент FormView в браузере при добавлении нового продукта Acme Coffee. Обратите внимание, что SupplierName
поля и CategoryName
, отображаемые в , ItemTemplate
больше не присутствуют, так как мы только что удалили их. При нажатии кнопки Вставка FormView выполняет те же действия, что и элемент управления DetailsView, добавляя новую запись в таблицу Products
. На рисунке 25 показаны сведения о продукте Acme Coffee в FormView после его вставки.
Рис. 24. Диктует InsertItemTemplate
интерфейс вставки 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.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по