Обзор событий, связанных со вставкой, обновлением и удалением (VB)
В этом руководстве мы рассмотрим события, возникающие до, во время и после операции вставки, обновления или удаления веб-элемента управления ASP.NET данных. Мы также увидим, как настроить интерфейс редактирования только для обновления подмножества полей продукта.
Введение
При использовании встроенных функций вставки, редактирования или удаления функций элементов управления GridView, DetailsView или FormView выполняется ряд шагов, когда конечный пользователь завершает процесс добавления новой записи или обновления или удаления существующей записи. Как описано в предыдущем руководстве, когда строка редактируется в GridView, кнопка "Изменить" заменяется кнопкой "Обновить" и "Отмена" и "BoundFields" превращается в TextBoxes. После обновления данных и нажатия кнопки "Обновить" конечный пользователь выполняет следующие действия при обратной отправке:
- GridView заполняет его ОбъектDataSource
UpdateParameters
уникальными полями идентификации измененной записи (черезDataKeyNames
свойство) вместе со значениями, введенными пользователем. - GridView вызывает метод ObjectDataSource
Update()
, который, в свою очередь, вызывает соответствующий метод в базовом объекте (ProductsDAL.UpdateProduct
в предыдущем руководстве). - Базовые данные, которые теперь включают обновленные изменения, отскок в GridView
Во время этой последовательности действий выполняется несколько событий, что позволяет создавать обработчики событий, чтобы добавить пользовательскую логику по мере необходимости. Например, до шага 1 событие GridView RowUpdating
запускается. На этом этапе можно отменить запрос на обновление, если возникла ошибка проверки. Update()
При вызове метода событие ObjectDataSource Updating
запускается, предоставляя возможность добавлять или настраивать значения любого из элементовUpdateParameters
. После завершения выполнения метода базового объекта ObjectDataSource вызывается событие ObjectDataSource Updated
. Обработчик событий для Updated
события может проверить сведения об операции обновления, например количество затронутых строк и наличие исключения. Наконец, после шага 2 событие GridView RowUpdated
запускается; обработчик событий для этого события может изучить дополнительные сведения об операции обновления, выполняемой только что.
На рисунке 1 показана эта серия событий и шагов при обновлении GridView. Шаблон события на рис. 1 не является уникальным для обновления с помощью GridView. Вставка, обновление или удаление данных из GridView, DetailsView или FormView создает одинаковую последовательность событий предварительного и последующего уровня для веб-элемента управления данными и ObjectDataSource.
Рис. 1. Ряд событий до и после событий при обновлении данных в GridView (щелкните, чтобы просмотреть полноразмерное изображение)
В этом руководстве мы рассмотрим использование этих событий для расширения встроенных возможностей вставки, обновления и удаления возможностей веб-элементов управления ASP.NET данных. Мы также увидим, как настроить интерфейс редактирования только для обновления подмножества полей продукта.
Шаг 1. Обновление полей иUnitPrice
продуктовProductName
В интерфейсы редактирования из предыдущего руководства должны быть включены все поля продукта, которые не были доступны только для чтения. Если бы мы удалили поле из GridView , скажем QuantityPerUnit
, при обновлении данных веб-элемент управления данными не будет задавать значение ObjectDataSource QuantityPerUnit
UpdateParameters
. ОбъектDataSource затем передает значение Nothing
UpdateProduct
в метод уровня бизнес-логики (BLL), который изменит столбец измененной записи QuantityPerUnit
базы данных на NULL
значение. Аналогичным образом, если необходимое поле, например ProductName
, удаляется из интерфейса редактирования, обновление завершится ошибкой с исключением "Имя_продукта" не допускает значение NULL. Причина этого поведения заключается в том, что ОбъектDataSource был настроен для вызова ProductsBLL
метода класса UpdateProduct
, который ожидал входной параметр для каждого поля продукта. Поэтому коллекция ObjectDataSource UpdateParameters
содержит параметр для каждого входного параметра метода.
Если требуется предоставить веб-элемент управления данными, позволяющий пользователю обновлять только подмножество полей, необходимо либо программно задать отсутствующие UpdateParameters
значения в обработчике событий ObjectDataSource Updating
, либо создать и вызвать метод BLL, который ожидает только подмножество полей. Давайте рассмотрим этот последний подход.
В частности, давайте создадим страницу, отображающую только ProductName
поля в UnitPrice
редактируемом GridView. Этот интерфейс редактирования GridView позволяет пользователю обновлять два отображаемых поля ProductName
и UnitPrice
. Так как этот интерфейс редактирования предоставляет только подмножество полей продукта, необходимо создать ObjectDataSource, который использует существующий метод BLL UpdateProduct
и имеет отсутствующие значения поля продукта, заданные программным способом в обработчике Updating
событий, или необходимо создать новый метод BLL, который ожидает только подмножество полей, определенных в GridView. В этом руководстве мы используем последний параметр и создадим перегрузку UpdateProduct
метода, которая принимает только три входных параметра: productName
, unitPrice
и productID
:
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Update, False)> _
Public Function UpdateProduct(productName As String, _
unitPrice As Nullable(Of Decimal), productID As Integer) _
As Boolean
Dim products As Northwind.ProductsDataTable = _
Adapter.GetProductByProductID(productID)
If products.Count = 0 Then
Return False
End If
Dim product As Northwind.ProductsRow = products(0)
product.ProductName = productName
If Not unitPrice.HasValue Then
product.SetUnitPriceNull()
Else
product.UnitPrice = unitPrice.Value
End If
Dim rowsAffected As Integer = Adapter.Update(product)
Return rowsAffected = 1
End Function
Как и исходный UpdateProduct
метод, эта перегрузка начинается с проверки наличия продукта в базе данных с указанным ProductID
. В противном случае возвращается False
сообщение, указывающее, что запрос на обновление сведений о продукте завершился ошибкой. В противном случае он обновляет существующие записи ProductName
продукта и UnitPrice
поля соответствующим образом и фиксирует обновление путем вызова метода TableAdapter Update()
, передавая экземпляр ProductsRow
.
С помощью этого дополнения к нашему ProductsBLL
классу мы готовы создать упрощенный интерфейс GridView. DataModificationEvents.aspx
Откройте папку EditInsertDelete
и добавьте GridView на страницу. Создайте объект ObjectDataSource и настройте его для использования ProductsBLL
класса с Select()
сопоставлением GetProducts
методов и сопоставлением его Update()
методов с UpdateProduct
перегрузкой, которая принимает только unitPrice
productName
входные параметры и productID
параметры ввода. На рисунке 2 показан мастер создания источника данных при сопоставлении метода ObjectDataSource Update()
с ProductsBLL
перегрузкой нового UpdateProduct
метода класса.
Рис. 2. Сопоставление метода ObjectDataSource Update()
с новой UpdateProduct
перегрузкой (щелкните, чтобы просмотреть изображение полного размера)
Так как в нашем примере изначально потребуется только возможность изменять данные, но не вставлять или удалять записи, используйте момент, чтобы явно указать, что методы ObjectDataSource Insert()
и методы не должны быть сопоставлены ни с какими из ProductsBLL
методов класса, перейдя на вкладки INSERT и Delete()
DELETE и выбрав (Нет) из раскрывающегося списка.
Рис. 3. Выберите (нет) В раскрывающемся списке для вкладок INSERT и DELETE (щелкните, чтобы просмотреть изображение полного размера)
После завершения работы мастера установите флажок "Включить редактирование" из смарт-тега GridView.
После завершения мастера создания источника данных и привязки к GridView Visual Studio создал декларативный синтаксис для обоих элементов управления. Перейдите в представление источника, чтобы проверить декларативную разметку ObjectDataSource, которая показана ниже:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Так как для методов и методов ObjectDataSource Insert()
нет сопоставлений, InsertParameters
нет или DeleteParameters
разделов.Delete()
Кроме того, так как Update()
метод сопоставляется с UpdateProduct
перегрузкой метода, которая принимает только три входных параметра, раздел UpdateParameters
имеет всего три Parameter
экземпляра.
Обратите внимание, что для свойства ObjectDataSource OldValuesParameterFormatString
задано значение original_{0}
. Это свойство устанавливается автоматически Visual Studio при использовании мастера настройки источника данных. Однако, так как наши методы BLL не ожидают передачи исходного ProductID
значения, удалите это назначение свойства полностью из декларативного синтаксиса ObjectDataSource.
Примечание.
Если вы просто удалите OldValuesParameterFormatString
значение свойства из окно свойств в представлении конструктора, свойство по-прежнему будет существовать в декларативном синтаксисе, но будет задано пустой строкой. Удалите свойство полностью из декларативного синтаксиса или из окно свойств задайте значение по умолчанию{0}
.
Хотя объект ObjectDataSource имеет UpdateParameters
только имя, цену и идентификатор продукта, Visual Studio добавил BoundField или CheckBoxField в GridView для каждого поля продукта.
Рис. 4. GridView содержит BoundField или CheckBoxField для каждого поля продукта (щелкните, чтобы просмотреть изображение полного размера)
Когда конечный пользователь редактирует продукт и нажимает кнопку "Обновить", GridView перечисляет те поля, которые не были доступны только для чтения. Затем он задает значение соответствующего параметра в коллекции ObjectDataSource UpdateParameters
значением, введенным пользователем. Если нет соответствующего параметра, GridView добавляет его в коллекцию. Таким образом, если gridView содержит BoundFields и CheckBoxFields для всех полей продукта, ОбъектDataSource в конечном итоге вызовет UpdateProduct
перегрузку, которая принимает во всех этих параметрах, несмотря на то, что декларативная разметка ObjectDataSource указывает только три входных параметра (см. рис. 5). Аналогичным образом, если в GridView есть некоторое сочетание полей продуктов, не доступных только для чтения, в GridView, которые не соответствуют входным параметрам перегрузки UpdateProduct
, при попытке обновления будет возникать исключение.
Рис. 5. GridView добавит параметры в коллекцию ObjectDataSource UpdateParameters
(щелкните, чтобы просмотреть изображение полного размера)
Чтобы объект ObjectDataSource вызвал UpdateProduct
перегрузку, которая принимает только имя, цену и идентификатор продукта, необходимо ограничить GridView редактируемыми полями только для ProductName
этого.UnitPrice
Это можно сделать, удалив другие boundFields и CheckBoxFields, задав для этих полей значение свойства True
других полей ReadOnly
или по какой-либо комбинации двух. В этом руководстве мы просто удалим все поля GridView, кроме ProductName
UnitPrice
полей BoundFields, после чего декларативная разметка GridView будет выглядеть следующим образом:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
Несмотря на то, что перегрузка UpdateProduct
ожидает три входных параметра, у нас есть только два BoundFields в GridView. Это связано с тем, что productID
входной параметр является значением первичного DataKeyNames
ключа и передается через значение свойства для измененной строки.
Наш GridView вместе с UpdateProduct
перегрузкой позволяет пользователю изменять только имя и цену продукта, не теряя ни одного из других полей продукта.
Рис. 6. Интерфейс позволяет редактировать только имя и цену продукта (щелкните, чтобы просмотреть изображение полного размера)
Примечание.
Как описано в предыдущем руководстве, важно включить состояние представления GridView (поведение по умолчанию). Если для свойства false
GridView EnableViewState
задано значение, возникает риск того, что одновременные пользователи непреднамеренно удаляют или редактируют записи.
UnitPrice
Улучшение форматирования
Хотя пример GridView, показанный на рисунке 6, UnitPrice
поле не отформатировано вообще, что приводит к отображению цены, в котором отсутствуют символы валюты и имеет четыре десятичных разряда. Чтобы применить форматирование валют для нередактируемых строк, просто задайте UnitPrice
для свойства BoundField DataFormatString
значение {0:c}
и его HtmlEncode
свойство False
.
Рис. 7. Задание UnitPrice
параметров DataFormatString
и HtmlEncode
свойств соответственно (щелкните, чтобы просмотреть изображение полного размера)
При этом изменении строки, не редактируемые, форматируют цену как валюту; Измененная строка, однако, по-прежнему отображает значение без символа валюты и с четырьмя десятичными знаками.
Рис. 8. Строки, не редактируемые, теперь форматируются как значения валют (щелкните, чтобы просмотреть изображение полного размера)
Инструкции по форматированию, указанные в DataFormatString
свойстве, можно применить к интерфейсу редактирования, задав для свойства BoundField ApplyFormatInEditMode
значение True
(значение по умолчанию False
). Укажите для этого свойства True
некоторое время.
Рис. 9. Задайте UnitPrice
для свойства BoundField ApplyFormatInEditMode
значение True
(щелкните, чтобы просмотреть изображение полного размера)
При этом изменении значение UnitPrice
отображаемой в редактируемой строке также форматируется как валюта.
Рис. 10. Значение измененной строки UnitPrice
теперь отформатировано как валюта (щелкните, чтобы просмотреть изображение полного размера)
Однако обновление продукта с символом валюты в текстовом поле, например $19,00, вызывает FormatException
исключение. Когда GridView пытается назначить пользовательские значения коллекции ObjectDataSource UpdateParameters
, не удается преобразовать UnitPrice
строку "$19.00" в Decimal
необходимый параметр (см. рис. 11). Чтобы устранить эту проблему, можно создать обработчик событий для события GridView RowUpdating
и проанализировать предоставленный пользователем UnitPrice
код в формате Decimal
валюты.
Событие GridView принимает в качестве второго параметра объект типа GridViewUpdateEventArgsRowUpdating
, который включает NewValues
словарь в качестве одного из его свойств, содержащих предоставленные пользователем значения, готовые к назначению коллекции ObjectDataSourceUpdateParameters
. Можно перезаписать существующее UnitPrice
значение в NewValues
коллекции с десятичным значением, проанализированным с помощью формата валюты со следующими строками кода в обработчике RowUpdating
событий:
Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
Handles GridView1.RowUpdating
If e.NewValues("UnitPrice") IsNot Nothing Then
e.NewValues("UnitPrice") = _
Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
System.Globalization.NumberStyles.Currency)
End If
End Sub
Если пользователь предоставил UnitPrice
значение (например, $19,00), это значение перезаписывается с десятичным значением, вычисляемым с помощью Decimal.Parse, анализ значения в виде валюты. Это правильно анализирует десятичное значение в случае любых символов валют, запятых, десятичных точек и т. д., а также использует перечисление NumberStyles в пространстве имен System.Globalization .
На рисунке 11 показана проблема, вызванная символами валют в предоставленном UnitPrice
пользователем, а также способ использования обработчика событий GridView RowUpdating
для правильного анализа таких входных данных.
Рис. 11. Значение измененной строки UnitPrice
теперь отформатировано как валюта (щелкните, чтобы просмотреть изображение полного размера)
Шаг 2. ЗапретNULL UnitPrices
Хотя база данных настроена для разрешения NULL
значений в Products
столбце таблицы UnitPrice
, может потребоваться запретить пользователям посещать эту конкретную NULL
UnitPrice
страницу. То есть, если пользователь не может ввести UnitPrice
значение при редактировании строки продукта, а не сохранить результаты в базе данных, которую мы хотим отобразить сообщение, информирующее пользователя о том, что на этой странице все измененные продукты должны иметь указанную цену.
Объект GridViewUpdateEventArgs
, переданный в обработчик событий GridView RowUpdating
, содержит Cancel
свойство, которое, если задано True
, завершает процесс обновления. Давайте расширим RowUpdating
обработчик событий, чтобы задать True
e.Cancel
и отобразить сообщение, объясняющее, почему UnitPrice
значение в NewValues
коллекции имеет значениеNothing
.
Начните с добавления веб-элемента управления Label На страницу с именем MustProvideUnitPriceMessage
. Этот элемент управления Label будет отображаться, если пользователь не может указать UnitPrice
значение при обновлении продукта. Задайте свойству Label Text
значение "Необходимо указать цену для продукта". Я также создал новый класс CSS с Styles.css
именем Warning
со следующим определением:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
Наконец, задайте для свойства Label CssClass
значение Warning
. На этом этапе конструктор должен отображать предупреждение в красном, полужирном, курсивном, дополнительном большом размере шрифта над GridView, как показано на рисунке 12.
Рис. 12. Над GridView добавлена метка (щелкните, чтобы просмотреть изображение полного размера)
По умолчанию эта метка должна быть скрыта, поэтому задайте его Visible
свойство False
в обработчике Page_Load
событий:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
MustProvideUnitPriceMessage.Visible = False
End Sub
Если пользователь пытается обновить продукт без указания UnitPrice
, мы хотим отменить обновление и отобразить метку предупреждения. Расширение обработчика событий GridView RowUpdating
следующим образом:
Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
Handles GridView1.RowUpdating
If e.NewValues("UnitPrice") IsNot Nothing Then
e.NewValues("UnitPrice") = _
Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
System.Globalization.NumberStyles.Currency)
Else
MustProvideUnitPriceMessage.Visible = True
e.Cancel = True
End If
End Sub
Если пользователь пытается сохранить продукт без указания цены, обновление отменяется и отображается полезное сообщение. Хотя база данных (и бизнес-логика) допускает s NULL
UnitPrice
, эта конкретная страница ASP.NET не поддерживается.
Рис. 13. Пользователь не может оставить UnitPrice
пустым (щелкните, чтобы просмотреть изображение полного размера)
До сих пор мы видели, как использовать событие GridView RowUpdating
для программного изменения значений параметров, назначенных коллекции ObjectDataSource UpdateParameters
, а также как полностью отменить процесс обновления. Эти понятия переносятся в элементы управления DetailsView и FormView, а также применяются к вставке и удалению.
Эти задачи также можно выполнять на уровне ObjectDataSource с помощью обработчиков событий для его Inserting
событий Updating
и Deleting
событий. Эти события возникают перед вызовом связанного метода базового объекта и предоставляют последнюю возможность изменить коллекцию входных параметров или отменить операцию прямо. Обработчики событий для этих трех событий передают объект типа ObjectDataSourceMethodEventArgs , имеющий два свойства:
- Отмена, которая, если задано
True
, отменяет выполняемую операцию. - InputParameters, который является коллекцией
InsertParameters
, или в зависимости от того, является ли обработчик событий дляInserting
объектаUpdateParameters
,Updating
илиDeleteParameters
Deleting
события
Чтобы проиллюстрировать работу со значениями параметров на уровне ObjectDataSource, давайте добавим detailsView на нашей странице, которая позволяет пользователям добавлять новый продукт. Этот элемент DetailsView будет использоваться для предоставления интерфейса для быстрого добавления нового продукта в базу данных. Чтобы сохранить согласованный пользовательский интерфейс при добавлении нового продукта, давайте разрешаем пользователю вводить только значения для ProductName
полей и UnitPrice
полей. По умолчанию эти значения, не предоставленные в интерфейсе вставки DetailsView, будут иметь NULL
значение базы данных. Однако мы можем использовать событие ObjectDataSource Inserting
для внедрения различных значений по умолчанию, как мы увидим в ближайшее время.
Шаг 3. Предоставление интерфейса для добавления новых продуктов
Перетащите DetailsView из панели элементов в конструктор над GridView, удалите его Height
и Width
свойства и привязите его к объекту ObjectDataSource, который уже присутствует на странице. Это добавит BoundField или CheckBoxField для каждого поля продукта. Так как мы хотим использовать этот DetailsView для добавления новых продуктов, необходимо проверить параметр "Включить вставку" из смарт-тега; Однако такой параметр отсутствует, так как метод ObjectDataSource Insert()
не сопоставляется с методом в ProductsBLL
классе (помните, что при настройке источника данных при настройке источника данных см. рис. 3).
Чтобы настроить ObjectDataSource, выберите ссылку "Настройка источника данных" из смарт-тега, запустите мастер. Первый экран позволяет изменить базовый объект, к которым привязан ОбъектDataSource; оставьте для него значение ProductsBLL
. На следующем экране перечислены сопоставления методов ObjectDataSource с базовым объектом. Несмотря на то, что мы явно указали, что методы Delete()
не должны быть сопоставлены с любыми методами, если перейти на вкладки INSERT и DELETE, вы увидите, что Insert()
сопоставление существует. Это связано с тем, что ProductsBLL
AddProduct
методы и DeleteProduct
методы используют DataObjectMethodAttribute
атрибут, чтобы указать, что они являются методами по умолчанию для Insert()
и Delete()
соответственно. Поэтому мастер ObjectDataSource выбирает их при каждом запуске мастера, если не указано другое значение явно.
Insert()
Оставьте метод, указывающий на AddProduct
метод, но снова задайте раскрывающийся список вкладки DELETE (Нет).
Рис. 14. Задайте раскрывающийся список вкладок INSERT (AddProduct
щелкните, чтобы просмотреть изображение полного размера)
Рис. 15. Задайте раскрывающийся список вкладки DELETE (Нет) (Щелкните, чтобы просмотреть изображение полного размера)
После внесения этих изменений декларативный синтаксис ObjectDataSource будет развернут для включения InsertParameters
коллекции, как показано ниже:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<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>
Повторное выполнение мастера добавило OldValuesParameterFormatString
свойство. Чтобы очистить это свойство, задав его значение по умолчанию ({0}
) или удалив его полностью из декларативного синтаксиса.
При использовании ObjectDataSource, предоставляющего возможности вставки, смарт-тег DetailsView теперь будет включать флажок "Включить вставку"; вернитесь в конструктор и проверьте этот параметр. Затем выполните синтаксический анализ detailsView, чтобы он имеет только два BoundFields - ProductName
и - и UnitPrice
CommandField. На этом этапе декларативный синтаксис DetailsView должен выглядеть следующим образом:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
На рисунке 16 показана эта страница при просмотре через браузер на этом этапе. Как вы видите, DetailsView перечисляет имя и цену первого продукта (Chai). Однако мы хотим, чтобы интерфейс вставки предоставлял пользователю возможность быстро добавлять новый продукт в базу данных.
Рис. 16. Представление DetailsView в настоящее время отрисовывается в режиме только для чтения (щелкните, чтобы просмотреть изображение полного размера)
Чтобы отобразить DetailsView в его режиме вставки, необходимо задать DefaultMode
для свойства Inserting
значение . Это отрисовывает DetailsView в режиме вставки при первом посещении и сохраняет его после вставки новой записи. Как показано на рисунке 17, такой объект DetailsView предоставляет быстрый интерфейс для добавления новой записи.
Рис. 17. DetailsView предоставляет интерфейс для быстрого добавления нового продукта (щелкните, чтобы просмотреть изображение полного размера)
Когда пользователь вводит имя продукта и цену (например, Acme Water и 1.99, как на рис. 17) и щелкает "Вставка", обратная обратная связь начинается, и начинается вставка рабочего процесса, кульминацией которого станет новая запись продукта, добавляемая в базу данных. DetailsView сохраняет свой интерфейс вставки, и GridView автоматически возвращается к источнику данных, чтобы включить новый продукт, как показано на рис. 18.
Рис. 18. Продукт Acme Water добавлен в базу данных
Хотя GridView на рис. 18 не отображает его, поля продукта, отсутствующие в интерфейсе CategoryID
DetailsView, SupplierID
QuantityPerUnit
и т. д., назначаются NULL
значения базы данных. Это можно увидеть, выполнив следующие действия.
- Перейдите в обозреватель серверов в Visual Studio
- Расширение
NORTHWND.MDF
узла базы данных - Щелкните правой
Products
кнопкой мыши узел таблицы базы данных - Выбор "Показать данные таблицы"
В этом списке Products
будут перечислены все записи в таблице. Как показано на рисунке 19, все столбцы нового продукта, отличные от ProductID
, ProductName
и UnitPrice
имеют NULL
значения.
Рис. 19. Поля продукта, не предоставленные в DetailsView, назначаются NULL
значения (щелкните, чтобы просмотреть изображение полного размера)
Возможно, мы хотим указать значение по умолчанию, отличное NULL
от одного или нескольких из этих значений столбцов, так как не является лучшим параметром по умолчанию или поскольку NULL
сам столбец базы данных не разрешает NULL
. Для этого можно программно задать значения параметров коллекции DetailsView InputParameters
. Это назначение можно сделать в обработчике событий для события DetailsView ItemInserting
или события ObjectDataSource Inserting
. Так как мы уже рассмотрели использование событий предварительного и постуровневого уровня на уровне веб-элемента управления данными, давайте рассмотрим события ObjectDataSource на этот раз.
Шаг 4. Назначение значенийCategoryID
иSupplierID
параметров
В этом руководстве мы предположим, что для нашего приложения при добавлении нового продукта через этот интерфейс он должен быть назначен CategoryID
и SupplierID
значение 1. Как упоминалось ранее, объект ObjectDataSource имеет пару событий предварительного и последующего уровня, которые запускаются во время процесса изменения данных. При вызове метода Insert()
объект ObjectDataSource сначала вызывает его Inserting
событие, а затем вызывает метод, с которым был сопоставлен его Insert()
метод, и, наконец, вызывает Inserted
событие. Обработчик Inserting
событий предоставляет нам одну последнюю возможность настроить входные параметры или отменить операцию прямо.
Примечание.
В реальном приложении вы, скорее всего, хотите разрешить пользователю указать категорию и поставщика или выбрать для них это значение на основе некоторых критериев или бизнес-логики (а не слепо выбирать идентификатор 1). Независимо от этого, в примере показано, как программно задать значение входного параметра из предварительного события ObjectDataSource.
Создайте обработчик событий для события ObjectDataSource Inserting
. Обратите внимание, что второй входной параметр обработчика событий является объектом типа ObjectDataSourceMethodEventArgs
, который имеет свойство для доступа к коллекции параметров (InputParameters
) и свойству для отмены операции (Cancel
).
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
End Sub
На этом этапе InputParameters
свойство содержит коллекцию ObjectDataSource InsertParameters
со значениями, назначенными в DetailsView. Чтобы изменить значение одного из этих параметров, просто используйте: e.InputParameters("paramName") = value
Таким образом, чтобы задать CategoryID
значения и SupplierID
значения 1, настройте Inserting
обработчик событий следующим образом:
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
e.InputParameters("CategoryID") = 1
e.InputParameters("SupplierID") = 1
End Sub
На этот раз при добавлении нового продукта (например, Acme Soda), CategoryID
для столбцов SupplierID
нового продукта задано значение 1 (см. рис. 20).
Рис. 20. Теперь новые продукты имеют значение CategoryID
SupplierID
1 (щелкните, чтобы просмотреть изображение полного размера)
Итоги
Во время редактирования, вставки и удаления веб-элемента управления данными и ObjectDataSource проходят через ряд событий предварительного и последующего выполнения. В этом руководстве мы изучили события предварительного уровня и узнали, как использовать их для настройки входных параметров или отмены операции изменения данных полностью из событий веб-элемента управления данными и ObjectDataSource. В следующем руководстве мы рассмотрим создание и использование обработчиков событий для событий после уровня.
Счастливое программирование!
Об авторе
Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 2.0 в 24 часах. Он может быть достигнут в mitchell@4GuysFromRolla.com. или через его блог, который можно найти на http://ScottOnWriting.NET.
Особое спасибо
Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты для этого руководства были Джеки Гоор и Лиз Шулок. Хотите просмотреть мои предстоящие статьи MSDN? Если да, упадите меня линию в mitchell@4GuysFromRolla.com.