Обзор событий, связанных со вставкой, обновлением и удалением (C#)
В этом руководстве мы рассмотрим использование событий, которые происходят до, во время и после операции вставки, обновления или удаления веб-элемента управления ASP.NET данных. Мы также посмотрим, как настроить интерфейс редактирования, чтобы обновить только подмножество полей продукта.
Введение
При использовании встроенных функций вставки, редактирования или удаления элементов управления GridView, DetailsView или FormView пользователь завершает процесс добавления новой записи, обновления или удаления существующей записи. Как мы уже говорили в предыдущем руководстве, при редактировании строки в GridПросмотре кнопка "Изменить" заменяется кнопкой "Обновить" и "Отмена", а boundFields превращается в TextBoxes. После того как пользователь обновит данные и нажмет кнопку Обновить, при обратной отправке выполняются следующие действия.
- GridView заполняет свои объекты ObjectDataSource
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
. Затем ObjectDataSource передает значение в null
UpdateProduct
метод уровня бизнес-логики (BLL), который изменяет столбец измененной записи QuantityPerUnit
базы данных на NULL
значение. Аналогичным образом, если обязательное поле, например ProductName
, удаляется из интерфейса редактирования, обновление завершится ошибкой с исключением "Столбец "ProductName" не допускает значений NULL". Причина такого поведения заключалась в том, что ObjectDataSource был настроен для вызова 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 bool UpdateProduct(string productName, decimal? unitPrice, int productID)
{
Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
if (products.Count == 0)
// no matching record found, return false
return false;
Northwind.ProductsRow product = products[0];
product.ProductName = productName;
if (unitPrice == null) product.SetUnitPriceNull();
else product.UnitPrice = unitPrice.Value;
// Update the product record
int rowsAffected = Adapter.Update(product);
// Return true if precisely one row was updated, otherwise false
return rowsAffected == 1;
}
Как и исходный UpdateProduct
метод, эта перегрузка начинается с проверки наличия продукта в базе данных с указанным ProductID
. В противном случае возвращается false
значение , указывающее, что запрос на обновление сведений о продукте завершился сбоем. В противном случае он соответствующим образом обновляет существующие ProductName
UnitPrice
поля и записи продукта и фиксирует обновление путем вызова метода TableAdapter Update()
, передавая ProductsRow
экземпляр .
С этим дополнением к нашему ProductsBLL
классу мы готовы создать упрощенный интерфейс GridView. Откройте в DataModificationEvents.aspx
папке EditInsertDelete
и добавьте GridView на страницу. Создайте объект ObjectDataSource и настройте его для использования ProductsBLL
класса с сопоставлением GetProducts
методов с Select()
перегрузкой UpdateProduct
Update()
, принимающей productName
только входные параметры , unitPrice
и productID
. На рисунке 2 показан мастер создания источника данных при сопоставлении метода ObjectDataSource Update()
с перегрузкой ProductsBLL
нового UpdateProduct
метода класса.
Рис. 2. Сопоставление метода ObjectDataSource Update()
с новой UpdateProduct
перегрузкой (щелкните для просмотра полноразмерного изображения)
Так как в нашем примере изначально требуется только возможность редактирования данных, но не для вставки или удаления записей, уделите некоторое время, чтобы явно указать, что методы ObjectDataSource Insert()
и Delete()
не должны быть сопоставлены ни с каким из ProductsBLL
методов класса, перейдя на вкладки INSERT и DELETE и выбрав (Нет) в раскрывающемся списке.
Рис. 3. Выберите (нет) в списке Drop-Down для вкладок 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()
и Delete()
, нет InsertParameters
разделов и DeleteParameters
. Кроме того, так как 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 для всех полей продукта, ObjectDataSource в конечном итоге вызовет перегрузку UpdateProduct
, которая принимает все эти параметры, несмотря на то, что декларативная разметка ObjectDataSource задает только три входных параметра (см. рис. 5). Аналогичным образом, если в GridView имеется какое-то сочетание полей продукта, не предназначенных только для чтения, которое не соответствует входным параметрам перегрузки UpdateProduct
, при попытке обновления возникнет исключение.
Рис. 5. GridView добавит параметры в коллекцию ObjectDataSource UpdateParameters
(щелкните для просмотра полноразмерного изображения)
Чтобы объект ObjectDataSource вызвал перегрузку UpdateProduct
, которая принимает только имя, цену и идентификатор продукта, необходимо ограничить GridView наличием редактируемых полей только ProductName
для и UnitPrice
. Это можно сделать, удалив другие BoundFields и CheckBoxFields, задав для свойства этих полей ReadOnly
значение true
или с помощью некоторого сочетания этих двух полей. В этом руководстве мы просто удалим все поля 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 RowUpdating
принимает в качестве второго параметра объект типа GridViewUpdateEventArgs, который включает NewValues
словарь в качестве одного из своих свойств, содержащий предоставленные пользователем значения, готовые к назначению коллекции ObjectDataSource UpdateParameters
. Мы можем перезаписать существующее UnitPrice
значение в NewValues
коллекции десятичным значением, проанализированным с помощью формата валюты со следующими строками кода в обработчике RowUpdating
событий:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
e.NewValues["UnitPrice"] =
decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
Если пользователь предоставил UnitPrice
значение (например, "$19,00"), это значение перезаписывается десятичным значением, вычисляемым методом Decimal.Parse, при анализе значения в виде валюты. При этом будет правильно проанализирован десятичный раздел в случае любых символов валют, запятых, десятичных запятых и т. д., а также будет использоваться перечисление NumberStyles в пространстве имен System.Globalization .
На рисунке 11 показана проблема, вызванная символами валюты в предоставленном UnitPrice
пользователем , а также способ использования обработчика RowUpdating
событий GridView для правильного анализа таких входных данных.
Рис. 11. Значение измененной строки UnitPrice
теперь отформатировано в виде валюты (щелкните для просмотра полноразмерного изображения)
Шаг 2. ЗапретNULL UnitPrices
Хотя база данных настроена UnitPrice
так, чтобы разрешить NULL
значения в Products
столбце таблицы, может потребоваться запретить пользователям, посещающим NULL
UnitPrice
эту страницу, указывать значение. То есть, если пользователю не удается ввести UnitPrice
значение при редактировании строки продукта, вместо сохранения результатов в базе данных необходимо отобразить сообщение, информирующее пользователя о том, что на этой странице все измененные продукты должны иметь указанную цену.
Объект GridViewUpdateEventArgs
, передаваемый в обработчик событий GridView RowUpdating
, содержит Cancel
свойство, которое, если задано значение true
, завершает процесс обновления. Давайте расширим RowUpdating
обработчик событий, чтобы задать значение e.Cancel
true
и отобразить сообщение, объясняющее причину UnitPrice
, если значение в NewValues
коллекции равно null
.
Для начала добавьте элемент управления Label Web на страницу с именем MustProvideUnitPriceMessage
. Этот элемент управления Метка будет отображаться, если пользователю не удается указать UnitPrice
значение при обновлении продукта. Задайте для свойства Label Text
значение "Вы должны указать цену на продукт". Я также создал новый класс CSS в с Styles.css
именем Warning
со следующим определением:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
Наконец, присвойте свойству CssClass
Label значение Warning
. На этом этапе Designer должно отображать предупреждающее сообщение красным, полужирным, курсивом, очень большим размером шрифта над GridView, как показано на рисунке 12.
Рис. 12. Над gridView добавлена метка (щелкните для просмотра полноразмерного изображения)
По умолчанию эта метка должна быть скрыта, поэтому присвойте ее Visible
свойству значение false
в обработчике Page_Load
событий:
protected void Page_Load(object sender, EventArgs e)
{
MustProvideUnitPriceMessage.Visible = false;
}
Если пользователь пытается обновить продукт без указания UnitPrice
, мы хотим отменить обновление и отобразить метку предупреждения. Дополните обработчик событий GridView RowUpdating
следующим образом:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
{
e.NewValues["UnitPrice"] =
decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
else
{
// Show the Label
MustProvideUnitPriceMessage.Visible = true;
// Cancel the update
e.Cancel = true;
}
}
Если пользователь пытается сохранить продукт без указания цены, обновление отменяется и отображается полезное сообщение. Хотя база данных (и бизнес-логика) позволяет NULL
UnitPrice
использовать объекты , эта конкретная страница ASP.NET — нет.
Рис. 13. Пользователь не может оставить UnitPrice
пустым (щелкните для просмотра полноразмерного изображения)
На данный момент мы видели, как использовать событие GridView RowUpdating
для программного изменения значений параметров, назначенных коллекции ObjectDataSource UpdateParameters
, а также как полностью отменить процесс обновления. Эти понятия переносятся на элементы управления DetailsView и FormView, а также применяются к вставке и удалению.
Эти задачи также можно выполнять на уровне ObjectDataSource с помощью обработчиков Inserting
событий , Updating
и Deleting
. Эти события возникают перед вызовом связанного метода базового объекта и предоставляют возможность в последний раз изменить коллекцию входных параметров или отменить операцию. Обработчикам событий для этих трех событий передается объект типа ObjectDataSourceMethodEventArgs , имеющий два интересующих свойства:
- Отмена, которая, если задано
true
значение , отменяет выполняемую операцию. - InputParameters, представляющий собой коллекцию
InsertParameters
,UpdateParameters
илиDeleteParameters
, в зависимости от того, является ли обработчик события ,Inserting
Updating
илиDeleting
Чтобы проиллюстрировать работу со значениями параметров на уровне ObjectDataSource, давайте добавим на страницу DetailsView, который позволяет пользователям добавлять новый продукт. Этот DetailsView будет использоваться для предоставления интерфейса для быстрого добавления нового продукта в базу данных. Чтобы обеспечить согласованность пользовательского интерфейса при добавлении нового продукта, давайте разрешим пользователю вводить только значения для ProductName
полей и UnitPrice
. По умолчанию значения, которые не предоставляются в интерфейсе вставки DetailsView, будут иметь NULL
значение базы данных. Однако мы можем использовать событие ObjectDataSource Inserting
для внедрения различных значений по умолчанию, как мы увидим вскоре.
Шаг 3. Предоставление интерфейса для добавления новых продуктов
Перетащите Элемент DetailsView из панели элементов в Designer над GridView, очистите его Height
свойства и Width
и привяжите его к объекту ObjectDataSource, который уже присутствует на странице. Это приведет к добавлению BoundField или CheckBoxField для каждого поля продукта. Так как мы хотим использовать этот DetailsView для добавления новых продуктов, необходимо проверка параметр Включить вставку из смарт-тега. Однако такой параметр отсутствует, так как метод ObjectDataSource Insert()
не сопоставлен с методом в ProductsBLL
классе (напомним, что для этого сопоставления задано значение (Нет) при настройке источника данных см. рис. 3.
Чтобы настроить ObjectDataSource, выберите ссылку Настройка источника данных из смарт-тега, запустив мастер. Первый экран позволяет изменить базовый объект, к которому привязан объект ObjectDataSource. Оставьте для него значение ProductsBLL
. На следующем экране перечислены сопоставления методов ObjectDataSource с базовыми объектами. Несмотря на то, что мы явно указали Insert()
, что методы и Delete()
не должны сопоставляться ни с какими методами, при переходе на вкладки INSERT и DELETE вы увидите, что сопоставление существует. Это связано с тем, что ProductsBLL
AddProduct
методы и DeleteProduct
используют DataObjectMethodAttribute
атрибут , чтобы указать, что они являются методами по умолчанию для Insert()
и Delete()
соответственно. Таким образом, мастер ObjectDataSource выбирает их каждый раз при запуске мастера, если не указано другое значение явно.
Insert()
Оставьте метод, указывающий на AddProduct
метод, но снова задайте для раскрывающегося списка вкладки DELETE значение (Нет).
Рис. 14. Задайте для списка AddProduct
Drop-Down вкладки INSERT значение Метод (щелкните для просмотра полноразмерного изображения)
Рис. 15. Присвойте списку Drop-Down на вкладке 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 теперь будет включать флажок Включить вставку; вернитесь к Designer и проверка этот параметр. Затем выполните синтаксический анализ 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 в настоящее время отображается в режиме Read-Only (щелкните для просмотра полноразмерного изображения)
Чтобы отобразить 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 void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
}
На этом этапе свойство содержит коллекцию ObjectDataSource InsertParameters
со значениями, InputParameters
назначенными из DetailsView. Чтобы изменить значение одного из этих параметров, просто используйте : e.InputParameters["paramName"] = value
. Поэтому, чтобы задать CategoryID
для и SupplierID
значение 1, настройте Inserting
обработчик событий следующим образом:
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
e.InputParameters["CategoryID"] = 1;
e.InputParameters["SupplierID"] = 1;
}
На этот раз при добавлении нового продукта (например, Acme Soda) CategoryID
столбцы и SupplierID
нового продукта имеют значение 1 (см. рис. 20).
Рис. 20. Для новых продуктов теперь заданы CategoryID
значения и SupplierID
1 (щелкните для просмотра полноразмерного изображения)
Сводка
Во время редактирования, вставки и удаления как веб-элемент управления данными, так и ObjectDataSource проходят через ряд событий предварительного и последующего уровня. В этом руководстве мы рассмотрели события предварительного уровня и узнали, как использовать их для настройки входных параметров или отмены операции изменения данных из веб-элемента управления данными и событий ObjectDataSource. В следующем руководстве мы рассмотрим создание и использование обработчиков событий для событий после уровня.
Счастливое программирование!
Об авторе
Скотт Митчелл (Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с Веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часа. Его можно связать по адресу mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.
Отдельная благодарность
Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты этого руководства — Джеки Гур и Лиз Шулок. Хотите ознакомиться с моими предстоящими статьями MSDN? Если да, опустите мне строку в mitchell@4GuysFromRolla.com.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по