Обзор вставки, обновления и удаления данных (C#)
В этом руководстве мы посмотрим, как сопоставить методы ObjectDataSource Insert(), Update() и Delete() с методами классов BLL, а также настроить элементы управления GridView, DetailsView и FormView для предоставления возможностей изменения данных.
Введение
В последних нескольких руководствах мы изучили, как отображать данные на странице ASP.NET с помощью элементов управления GridView, DetailsView и FormView. Эти элементы управления просто работают с данными, предоставленными им. Как правило, эти элементы управления доступом к данным через использование элемента управления источниками данных, например ObjectDataSource. Мы видели, как ObjectDataSource выступает в качестве прокси-сервера между страницей ASP.NET и базовыми данными. Когда GridView должен отображать данные, он вызывает его метод ObjectDataSource Select()
, который, в свою очередь, вызывает метод из уровня бизнес-логики (BLL), который вызывает метод в соответствующем уровне доступа к данным (DAL) TableAdapter, который, в свою очередь, отправляет SELECT
запрос в базу данных Northwind.
Помните, что при создании TableAdapters в DAL в первом руководстве Visual Studio автоматически добавил методы для вставки, обновления и удаления данных из базовой таблицы базы данных. Кроме того, при создании уровня бизнес-логики мы разработали методы в BLL, которые вызываются в эти методы изменения данных DAL.
В дополнение к его Select()
методу ОбъектDataSource также имеет Insert()
Update()
методы и Delete()
методы. Как и в методе Select()
, эти три метода можно сопоставить с методами в базовом объекте. При настройке вставки, обновления или удаления данных элементы управления GridView, DetailsView и FormView предоставляют пользовательский интерфейс для изменения базовых данных. Этот пользовательский интерфейс вызывает Insert()
Update()
методы Delete()
и методы ObjectDataSource, которые затем вызывают связанные с базовым объектом методы (см. рис. 1).
Рис. 1. Методы ObjectDataSource Insert()
Update()
и Delete()
служат прокси-сервером в BLL (щелкните, чтобы просмотреть изображение полного размера)
В этом руководстве показано, как сопоставить методы ObjectDataSource Insert()
Update()
и Delete()
методы с методами классов в BLL, а также настроить элементы управления GridView, DetailsView и FormView для предоставления возможностей изменения данных.
Шаг 1. Создание веб-страниц вставки, обновления и удаления учебников
Прежде чем начать изучение вставки, обновления и удаления данных, сначала рассмотрим, как создать страницы ASP.NET в проекте веб-сайта, который нам потребуется для этого руководства и следующих нескольких. Сначала добавьте новую папку с именем EditInsertDelete
. Затем добавьте в нее следующие ASP.NET страницы, чтобы связать каждую страницу с главной страницей Site.master
:
Default.aspx
Basics.aspx
DataModificationEvents.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
Рис. 2. Добавление страниц ASP.NET для учебников, связанных с изменением данных
Как и в других папках, 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
Откройте страницу, перетащите ОбъектDataSource из панели элементов в конструктор и щелкните ссылку "Настроить источник данных" из смарт-тега. ProductsBLL
Так как это единственный класс BLL, который предоставляет методы редактирования, вставки и удаления, настройте ObjectDataSource для использования этого класса.
Рис. 5. Настройка ObjectDataSource для использования ProductsBLL
класса (щелкните, чтобы просмотреть изображение полного размера)
На следующем экране можно указать, какие методы ProductsBLL
класса сопоставляются с объектом ObjectDataSource Select()
, Insert()
Update()
и Delete()
выбрав соответствующую вкладку и выбрав метод из раскрывающегося списка. Рис. 6, который должен выглядеть знакомым к настоящему моменту, сопоставляет метод ObjectDataSource Select()
с ProductsBLL
методом класса GetProducts()
. Update()
Методы Insert()
и Delete()
методы можно настроить, выбрав соответствующую вкладку в списке вверху.
Рис. 6. Получение объекта ObjectDataSource All of the Products (Щелкните, чтобы просмотреть изображение полного размера)
На рисунках 7, 8 и 9 показаны вкладки UPDATE, INSERT и DELETE ObjectDataSource. Настройте эти вкладки таким образом, чтобы Insert()
Update()
Delete()
методы и , соответственно, вызывают ProductsBLL
класс UpdateProduct
AddProduct
и DeleteProduct
методы.
Рис. 7. Сопоставление метода ObjectDataSource Update()
с методом ProductBLL
класса UpdateProduct
(щелкните, чтобы просмотреть изображение полного размера)
Рис. 8. Сопоставление метода ObjectDataSource Insert()
с методом ProductBLL
добавления 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 с помощью мастера перейдите в представление Source, чтобы проверить созданную декларативную разметку. Тег <asp:ObjectDataSource>
задает базовый объект и методы для вызова. Кроме того, существуют и сопоставляются InsertParameters
UpdateParameters
DeleteParameters
входные параметры для ProductsBLL
класса AddProduct
и UpdateProduct
DeleteProduct
методов:
<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
s, когда ОбъектDataSource настроен для вызова метода select, который ожидает входной параметр (например GetProductsByCategoryID(categoryID)
). Как мы увидим вскоре, значения для этих DeleteParameters
, UpdateParameters
и InsertParameters
автоматически задаются GridView, DetailsView и FormView перед вызовом объекта ObjectDataSource Update()
Insert()
или Delete()
метода. Эти значения также можно задать программным способом, так как мы обсудим в будущем руководстве.
Одним из побочных эффектов использования мастера для настройки ObjectDataSource является то, что Visual Studio задает для свойства OldValuesParameterFormatString значениеoriginal_{0}
. Это значение свойства используется для включения исходных значений редактируемых данных и полезно в двух сценариях:
- Если при редактировании записи пользователи могут изменить значение первичного ключа. В этом случае необходимо указать новое значение первичного ключа и исходное значение первичного ключа, чтобы запись с исходным значением первичного ключа была найдена и обновлена соответствующим образом.
- При использовании оптимистического параллелизма. Оптимистическая параллелизм — это метод, позволяющий двум одновременным пользователям не перезаписывать изменения друг друга и статью для будущего руководства.
Свойство OldValuesParameterFormatString
указывает имя входных параметров в методах обновления и удаления базового объекта для исходных значений. Мы обсудим это свойство и его назначение более подробно при изучении оптимистического параллелизма. Теперь я приведу его, однако, потому что методы BLL не ожидают исходных значений, поэтому важно удалить это свойство. Если OldValuesParameterFormatString
свойство не задано по умолчанию ({0}
) приведет к ошибке, когда веб-элемент управления данными пытается вызвать объект ObjectDataSource или Delete()
методы, так как ObjectDataSource Update()
попытается передать оба UpdateParameters
параметра или DeleteParameters
параметры исходного значения.
Если это не очень ясно на этом этапе, не беспокойтесь, мы рассмотрим это свойство и его служебную программу в будущем руководстве. Теперь просто обязательно удалите это объявление свойства полностью из декларативного синтаксиса или задайте значение по умолчанию ({0}).
Примечание.
Если вы просто очищаете OldValuesParameterFormatString
значение свойства из окно свойств в представлении конструктора, свойство по-прежнему будет существовать в декларативном синтаксисе, но задается пустой строкой. К сожалению, это по-прежнему приведет к той же проблеме, описанной выше. Поэтому либо удалите свойство из декларативного синтаксиса, либо из окно свойств задайте значение по умолчанию{0}
.
Шаг 3. Добавление веб-элемента управления данными и настройка его для изменения данных
После добавления ObjectDataSource на страницу и настройки мы готовы добавить веб-элементы управления данными на страницу для отображения данных и предоставления средств для его изменения конечным пользователем. Мы рассмотрим GridView, DetailsView и FormView отдельно, так как эти веб-элементы управления данными отличаются возможностями изменения и конфигурации данных.
Как мы увидим в оставшейся части этой статьи, добавление очень простого редактирования, вставки и удаления поддержки с помощью элементов управления GridView, DetailsView и FormView очень просто, как проверка нескольких флажков. Есть много тонкостей и пограничных вариантов в реальном мире, которые делают предоставление такой функциональности более вовлеченной, чем просто точка и щелчок. Однако в этом руководстве основное внимание уделяется исключительно доказательству возможностей простого изменения данных. В будущих руководствах рассматриваются проблемы, которые, несомненно, возникают в реальном мире.
Удаление данных из GridView
Начните с перетаскивания GridView из панели элементов в конструктор. Затем привязать ОбъектDataSource к 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 задаются на основе метаданных базового поля. Например,
ProductID
CategoryName
поля иSupplierName
поля помечены как доступные только для чтения в иProductsDataTable
поэтому не должны обновляться при редактировании. Для этого для этих свойств BoundFields 'ReadOnly задано значениеtrue
. - Свойство DataKeyNames назначается полям первичного ключа базового объекта. Это важно при использовании GridView для редактирования или удаления данных, так как это свойство указывает поле (или набор полей), которое уникально идентифицирует каждую запись. Дополнительные сведения о
DataKeyNames
свойстве см. в руководстве "Master/Details" с помощью главного элемента GridView с помощью руководства detailsView .
Хотя 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, поддерживающих редактирование или удаление (поведение по умолчанию). Если для свойства false
GridView EnableViewState
задано значение , поведение редактирования и удаления будет работать нормально для одного пользователя, но если есть одновременные пользователи, удаляющие данные, существует возможность случайного удаления или изменения записей, которые они не планировали.
Это же предупреждение также относится к DetailsViews и FormViews.
Чтобы добавить возможности удаления в GridView, просто перейдите к смарт-тегу и установите флажок "Включить удаление".
Рис. 10. Установите флажок "Включить удаление"
Проверка флажка "Включить удаление" из смарт-тега добавляет CommandField в GridView. CommandField отображает столбец в GridView с кнопками для выполнения одной или нескольких следующих задач: выбор записи, редактирование записи и удаление записи. Ранее мы видели CommandField в действии с выбором записей в главном или подробном представлении с помощью примера Master GridView с руководством detailsView .
CommandField содержит ряд свойств, указывающих ShowXButton
, какая серия кнопок отображается в CommandField. Проверив флажок "Включить удаление" CommandField, свойство true
которого ShowDeleteButton
было добавлено в коллекцию столбцов GridView.
<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
свойства ОбъектDataSource пытается передать оба productID
параметра и original_ProductID
входные параметры в DeleteProduct
метод. DeleteProduct
Однако принимает только один входной параметр, поэтому исключение. При удалении OldValuesParameterFormatString
свойства (или его настройки {0}
) объект ObjectDataSource не пытается передать исходный входной параметр.
Рис. 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 (при необходимости) и задать для его свойства true
значениеShowEditButton
. Как мы видели ранее, 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, обновление завершится ошибкой с тем же исключением, что и "Имя_продукта", указанное выше, не допускает значение NULL. - Форматирование интерфейса редактирования оставляет желать многого. Отображается
UnitPrice
с четырьмя десятичными знаками.CategoryID
В идеале значенияSupplierID
содержат dropDownLists, которые перечисляют категории и поставщики в системе.
Это все недостатки, с которыми мы должны жить сейчас, но будут рассмотрены в будущих руководствах.
Вставка, редактирование и удаление данных с помощью DetailsView
Как мы видели в предыдущих руководствах, элемент управления DetailsView отображает одну запись за раз и, как GridView, позволяет редактировать и удалять отображаемую в данный момент запись. Интерфейс конечного пользователя с редактированием и удалением элементов из DetailsView и рабочего процесса из ASP.NET стороне идентичен элементу GridView. Где DetailsView отличается от GridView, он также предоставляет встроенную поддержку вставки.
Чтобы продемонстрировать возможности изменения данных в GridView, начните с добавления DetailsView на Basics.aspx
страницу над существующим GridView и привязать его к существующему объекту ObjectDataSource с помощью смарт-тега DetailsView. Затем удалите сведения и Width
свойства DetailsView Height
и проверьте параметр "Включить разбиение по страницам" из смарт-тега. Чтобы включить редактирование, вставку и удаление поддержки, просто установите флажки "Включить редактирование", "Включить вставку" и "Включить удаление" в смарт-теге.
Рис. 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 по умолчанию отображается в конце коллекции столбцов. Так как поля DetailsView отображаются в виде строк, CommandField отображается в виде строки с кнопками Insert, Edit и Delete в нижней части DetailsView.
Рис. 18. Настройка DetailsView для поддержки редактирования, вставки и удаления (щелкните, чтобы просмотреть изображение полного размера)
Нажатие кнопки "Удалить" запускает ту же последовательность событий, что и в GridView: обратная обратная связь; за которым следует DetailsView, заполняющий объект ObjectDataSource DeleteParameters
на DataKeyNames
основе значений, и завершился вызовом метода ObjectDataSource Delete()
, который фактически удаляет продукт из базы данных. Редактирование в DetailsView также работает так же, как и в GridView.
Для вставки конечный пользователь отображает новую кнопку, которая при нажатии отображает DetailsView в режиме вставки. При использовании режима вставки кнопка "Создать" заменяется кнопками "Вставка" и "Отмена" и отображаются только те свойства BoundFields, для которых InsertVisible
задано значение ( true
по умолчанию). Эти поля данных, определенные как поля автоматического увеличения, например ProductID
, имеют свойство InsertVisible , заданное false
при привязке DetailsView к источнику данных с помощью смарт-тега.
При привязке источника данных к DetailsView с помощью смарт-тега Visual Studio задает InsertVisible
свойство только false
для полей автоматического увеличения. Поля только для чтения, например CategoryName
и SupplierName
, будут отображаться в пользовательском интерфейсе "в режим вставки", если их InsertVisible
свойство не задано false
явным образом. Чтобы задать свойства false
этих двух полей в декларативном синтаксисе DetailsView или с помощью ссылки "Изменить поля" InsertVisible
в смарт-теге. На рисунке 19 показано, как false
задать InsertVisible
свойства, щелкнув ссылку "Изменить поля".
Рис. 19. Northwind Traders теперь предлагает acme чай (щелкните, чтобы просмотреть изображение полного размера)
После задания InsertVisible
свойств просмотрите Basics.aspx
страницу в браузере и нажмите кнопку "Создать". На рисунке 20 показан Элемент DetailsView при добавлении нового напитка, Acme Tea, в нашу линейку продуктов.
Рис. 20. Northwind Traders теперь предлагает acme чай (щелкните, чтобы просмотреть изображение полного размера)
После ввода сведений о чае Acme и нажатии кнопки "Вставить", после этого в таблицу базы данных будет 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 и FormView с веб-элементами управления TextBox для сбора входных данных пользователя и веб-элементов управления "Кнопка" для кнопок "Создать", "Изменить", "Удалить", "Вставить", "Обновить" и "Отмена". Кроме того, для свойства FormView DataKeyNames
задано поле первичного ключа (ProductID
) объекта, возвращаемого ObjectDataSource. Наконец, установите флажок "Включить разбиение по страницам" в смарт-теге FormView.
Ниже показана декларативная разметка для FormView ItemTemplate
после привязки FormView к ObjectDataSource. По умолчанию каждое поле продукта, отличное от логического значения, привязано к Text
свойству веб-элемента управления Label, а каждое поле логического значения (Discontinued
) привязано к Checked
свойству отключенного веб-элемента управления CheckBox. Чтобы кнопки "Создать", "Изменить" и "Удалить", чтобы активировать определенное поведение FormView при щелчке, крайне важно, чтобы их CommandName
значения были заданы New
как , 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 или ImageButtonCommandName
, свойство которого задано для удаления, приводит к обратной отправке, заполняет объектDataSource на основе значения FormView DataKeyNames
и вызывает метод ObjectDataSource DeleteParameters
Delete()
.
При нажатии кнопки "Изменить" происходит обратная связь, и данные отскокируются к EditItemTemplate
объекту, который отвечает за отрисовку интерфейса редактирования. Этот интерфейс включает веб-элементы управления для редактирования данных вместе с кнопками "Обновление и отмена". Значение по умолчанию EditItemTemplate
, созданное Visual Studio, содержит метку для всех полей автоматического увеличения (ProductID
), Текстовое поле для каждого поля, отличного от логического значения, и флажок для каждого поля логического значения. Это поведение очень похоже на автоматически созданные BoundFields в элементах управления GridView и DetailsView.
Примечание.
Одна небольшая проблема автоматического EditItemTemplate
создания FormView заключается в том, что он отображает веб-элементы управления TextBox для тех полей, которые доступны только для чтения, например CategoryName
и SupplierName
. Мы посмотрим, как учесть это в ближайшее время.
Элементы управления TextBox в свойстве EditItemTemplate
Text
привязаны к значению соответствующего поля данных с помощью двусторонней привязки данных. Двусторонняя привязка данных, обозначаемая <%# Bind("dataField") %>
, выполняет привязку данных как при привязке данных к шаблону, так и при заполнении параметров ObjectDataSource для вставки или редактирования записей. То есть, когда пользователь нажимает кнопку "Изменить" из этого ItemTemplate
метода, Bind()
метод возвращает указанное значение поля данных. После внесения изменений и нажатия кнопки "Обновить" значения, которые соответствуют заданным полям данных, Bind()
применяются к объекту ObjectDataSource UpdateParameters
. Кроме того, односторонняя привязка данных, обозначаемая <%# Eval("dataField") %>
, получает только значения полей данных при привязке данных к шаблону и не возвращает введенные пользователем значения в параметры источника данных при обратной отправке.
В следующей декларативной разметке показана функция FormView EditItemTemplate
. Обратите внимание, что Bind()
метод используется в синтаксисе привязки данных здесь, и что веб-элементы управления Update и Cancel Button имеют соответствующие 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. Обратите внимание, что поля, CategoryName
отображаемые в спискеItemTemplate
, больше не присутствуют, так как мы только что SupplierName
удалили их из .EditItemTemplate
Когда кнопка "Обновить" нажимается на FormView, выполняется в той же последовательности шагов, что и элементы управления GridView и DetailsView.
Рис. 23. По умолчанию EditItemTemplate
отображается каждое редактируемое поле продукта в виде текстового поля или флажка (щелкните, чтобы просмотреть изображение полного размера)
После нажатия кнопки "Вставка" происходит обратная связь FormView ItemTemplate
. Однако данные не привязаны к FormView, так как добавляется новая запись. Интерфейс InsertItemTemplate
включает веб-элементы управления для добавления новой записи вместе с кнопками "Вставка и отмена". Значение по умолчанию InsertItemTemplate
, созданное Visual Studio, содержит текстовое поле для каждого поля, отличного от логического значения, и флажок для каждого логического поля, аналогично интерфейсу, созданному 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
с этим, необходимо удалить эти текстовые поля из .InsertItemTemplate
На рисунке 24 отображается FormView в браузере при добавлении нового продукта Acme Coffee. Обратите внимание, что поля, CategoryName
отображаемые в спискеItemTemplate
, больше не присутствуют, так как мы только что SupplierName
удалили их. При нажатии кнопки "Вставка" 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 благодаря веб-элементам управления данных и ObjectDataSource. Однако простая точка и методы щелчка отображают довольно хрупкий и наивный пользовательский интерфейс изменения данных. Чтобы обеспечить проверку, внедрить программные значения, корректно обрабатывать исключения, настраивать пользовательский интерфейс и т. д., необходимо полагаться на множество методов, которые будут обсуждаться в следующих нескольких руководствах.
Счастливое программирование!
Об авторе
Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 2.0 в 24 часах. Он может быть достигнут в mitchell@4GuysFromRolla.com. или через его блог, который можно найти на http://ScottOnWriting.NET.