在前面几章,我们简单介绍了如何在asp.net2.0中使用GridView, DetailsView, FormView等控件显示数据,这几种控件可以很简单的利用提供给它们的数据来工作,通常这些控件通过data source control 来访问数据 ,例如使用ObjectDataSource , 从这里我们可以清楚知道data source control 扮演着一个asp.net2.0 page 和底层数据间的代理角色。当GridView 需要显示数据时, 他调用了ObjectDataSource’s Select() 方法 , 后者会调用业务逻辑层中合适的方法。接着业务逻辑层的方法会call数据访问层的方法,数据访问层会发送select查询给Northwind database。
想想在第一章我们在数据访问层里创建了TableAdapters , Visual Studio 会自动添加访问底层数据库的 inserting, updating, 和 deleting  方法 ,之前在第二章Creating a Business Logic Layer 我们设计了一些通过数据访问层修改数据的业务逻辑层方法
除了提供Select()方法 ,ObjectDataSource 还有Insert(), Update(), 和Delete() 方法. 就像 Select() 方法一样, 这三个方法映射到底层数据的插入、更新、删除,当配置好插入、修改、删除数据属性 , GridView, DetailsView, 和 FormView 控件可以提供修改数据的用户接口. 这个接口调用ObjectDataSource 的Insert(), Update(), and Delete() 方法,ObjectDataSource调用底层对象相关联的方法 (see Figure 1).
 
Figure 1: ObjectDataSource’s Insert(), Update(), 和 Delete()扮演着业务逻辑层的代理。
这一指南中,我们将了解如何把ObjectDataSource’s  Insert(), Update(), and Delete()映射到业务逻辑层。还有如何正确配置GridView, DetailsView, and FormView控件数据操作。
Step 1:建立Insert, Update, and Delete Tutorials Web Pages
在我们了解如何insert, update,delete数据之前,先让我们花一些时间做些准备工作,在我们web site 项目添加一些page  建立一个文件夹EditInsertDelete. 接着在这个文件下加入以下的webpage并把这些page与site.master 这个master page相关联
• Default.aspx
• Basics.aspx
• DataModificationEvents.aspx
• ErrorHandling.aspx
• UIValidation.aspx
• CustomizedUI.aspx
• OptimisticConcurrency.aspx
• ConfirmationOnDelete.aspx
• UserLevelAccess.aspx


Figure 2: Add the ASP.NET Pages for the Data Modification-Related Tutorials

根以前一样,EditInsertDelete 文件夹中的default.aspx会把这章所讲述内容的列在上面,所以我们把SectionLevelTutorialListing.ascx 加入到default.aspx中


Step 3:添加并配置一个Data Web Control 
   当我们添加配置完ObjectDataSource ,现在准备在页面上添加一个data Web control,这个控件不仅要能显示数据还可以让最终用户修改数据,考虑到GridView, DetailsView, and FormView在数据修改和配置的区别。
在这片文档的后面我们将发现给GridView, DetailsView, and FormView controls添加数据修改能力是非常容易的。现实中其实它们功能非常强大,在本指南中,我们只是重点说明如何进行数据修改,下面我们分别解释
Deleting Data from the GridView
Start by dragging a GridView from the Toolbox onto the Designer. Next, bind the ObjectDataSource to the GridView by selecting it from the drop-down list in the GridView’s smart tag. At this point the GridView’s declarative markup will be:

好现在开始,从toolbox往设计界面拖一个GridView ,接着,点击GridView的智能标记把ObjectDataSource 绑定上,页面上的GridView代码将是这样
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">
    <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>

通过智能标记把ObjectDataSource绑定到GridView有两个好处
从ObjectDataSource返回的字段会自动建立BoundFields and CheckBoxField,此外BoundField and CheckBoxField将会根据底层的字段设定相应的属性。例如,ProductID, CategoryName, and SupplierName 字段在ProductsDtaTable里为只读,不能被修改和编辑,所以,这些BoundFields的ReadOnly属性被设为true。
DataKeyNames 属性被设为底层数据的primary key字段,这个属性是GridView编辑,删除数据标识每个具体记录的标示。
GridView可以通过属性窗口或者在代码中声明,后一种做法需要你手动添加BoundField and DataKeyNames标记
GridView提供了内置的行一级的编辑和删除的功能,配置GridView支持删除,会添加一格Delete button 列,当用户点击某一行的Delete Button 会引起会送,并且GridView执行以下步骤。

1. ObjectDataSource的 DeleteParameters 被赋值
2. ObjectDataSource的 Delete 方法被调用,删除实际的记录
3. GridView 通过调用ObjectDataSource的select()方法被重新绑定。
被赋给DeleteParameters是这一行的DataKeyNames字段的值,所以GridView的DataKeyNames必须要设置正确,如果这个值丢失了,DeleteParameters 在第一步时将被赋以null值,所以不会得到正确的结果。
Figure 10: Check the Enable Deleting Checkbox
简单的通过GridView的智能标记,点击Enable Deleting Checkbox 就可以让GridView具有删除功能。
点击Enable Deleting checkbox GridView会添加一列CommandField。CommandField会根据具体任务表现为带有一个或多个按钮列:这些按钮有选择数据,编辑数据,删除数据,具体看前面的Master/Detail Using a Selectable Master GridView with a Details DetailView 指南
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" /> //注意这里
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>


Figure 11: The CommandField Adds a Column of Delete Buttons
到这里我们为DataGridView添加的删除数据的功能,通过访问我们的例子,可以看到删除按钮已经出现在我的眼前。如图所示
If you’ve been building this tutorial from the ground up on your own, when testing this page clicking the Delete button will raise an exception. Continue reading to learn as to why these exceptions were raised and how to fix them.
如果你已经生成这个指南,当点击页面上的delete按钮来测试这个功能会获得一个异常,接下来我们来学习如何解决它。
Note: If you’re following along using the download accompanying this tutorial, these problems have already been accounted for. However, I encourage you to read through the details listed below to help identify problems that may arise and suitable workarounds.
注意:如果你下载了本指南的例子,会发现这个错误已经被排除。然而,最好读者能够越仔细阅读以下部分。它会给你更多的益处。
当你试图去删除一个product,你会得到一个“ObjectDataSource 'ObjectDataSource1' could not find a non-generic method 'DeleteProduct' that has parameters: productID, original_ProductID,”(意思是指objectDataSource1不存在一个非范型的参数为productID, original_ProductID的DeleteProduct的方法)的异常。这应该是你忘记删除ObjectDataSource的OldValuesParameterFormatString的属性。如果这个属性被声明,ObjectDataSourc会试图相相应的方法传递productID and original_ProductID 两个输入参数,而现实只能接收一个,因此解决这个异常的办法就是,去除OldValuesParameterFormatString 属性或这个把它的设为{0},让ObjectDatasource不要传递原始值

尽管删除了OldValuesParameterFormatString属性,依旧会得到一个“The DELETE statement conflicted with the REFERENCE constraint 'FK_Order_Details_Products'.”的异常,这是因为Northwind在Order Details and Products 这些表里存在外键,所以当product的数据与Order Details有联系时是不能被删除的,实际上Northwind数据库的porduct表里的记录至少与一个Order Details 的记录有联系。

在这个指南里,我们先删除Order Details的所有记录。实际上我们在程序中可以做如下修改。
• 切换到另一个窗口下管理order details信息
• 修改DeleteProduct方法使之包括逻辑上删除指定的order details
• 修改TableAdapter的Sql语句。让它删除指定的order details

现在让我们删除所有的Order Details表里的所有记录,在vs里切换到Server Exploer 窗口,右击NORTHWND.MDF节点,建立新的查询,在查询窗口运行以下语句DELETE FROM [Order Details]

清除了Order Details表里的数据,点击Delete button将会删除product并且不会产生任何错误,如果不能删除数据,检查是否GridView的DataKeyNames属性设置为primarykey 字段(ProductID)
注意:点击Delete button 就会引起回发数据也就被删除了,这是比较危险如果用户偶然点错了按钮,后面的指南将会说明如何增加删除数据前客户端的确认
Editing Data with the GridView
与删除一样,GridView也提供了内置的行一级的编辑功能。把GridView配置为可编辑的将会添加一列编辑按钮。用户点击后GridVeiw变为可编辑的。单元格将变为包含原始数据的TextBox,编辑按钮变为UpDate 和 Cancel 按钮。修改完成后可以点击UpDate button 提交,或Cancel button 作废,GridView将会变为编辑前的样子。
用户点击某一行的Edit button,GridView就会执行以下步骤
1. GridView的EditItemIndex属性被赋予那一行的索引。
2. GridView重新绑定。从而ObjectDataSource调用Select方法
3. 索引为EditItemIndex的行被表现为”edit”mode”,这种模式下,Eidt button会被替换为 UpDate Button 和 Cancel button, ReadOnly属性为false的BoundFields变为TextBox 控件,并且它的Text值为原始值

At this point the markup is returned to the browser, allowing the end user can to make any changes to the row’s data. When the user clicks the Update button, a postback occurs and the GridView performs the following steps:
现在当用户修改数据,点击UpDate button ,将会引发会送,GridView执行以下步骤
1. The ObjectDataSource’s UpdateParameters value(s) are assigned the values entered by the end user into the GridView’s editing interface
2. The ObjectDataSource’s Update() method is invoked, updating the specified record
3. The GridView rebinds itself to the ObjectDataSource by invoking its Select() method
1. 用户输入的数据被赋予ObjectDataSource的UpdateParameters
2. ObjectDataSource的UpDate()方法被调用,更新相应的记录
3. GridView重新绑定

The primary key values assigned to the UpdateParameters in Step 1 come from the values specified in the DataKeyNames property, whereas the non-primary key values come from the text in the TextBox Web controls for the edited row. As with deleting, it is vital that a GridView’s DataKeyNames property be correctly set. If it’s missing, the UpdateParameters primary key value will be assigned a null value in Step 1, which in turn will not result in any updated records in Step 2.
DataKeyNames变量的值通过UpDateParameters传入给primary。非parimary key字段的值被赋予当前行中的TextBox的值。
Editing functionality can be activated by simply checking the Enable Editing checkbox in the GridView’s smart tag.
通过简单的点击GridView的智能标记,选中Enable Editing ,就可以为GrirdView添加编辑功能。如同delete一样DataKeyName属性是否设置正确,十分重要,如果丢失,UpDateParameters的主键值将被赋予null。这回引发错误结果

Figure 15: Check the Enable Editing Checkbox

Checking the Enable Editing checkbox will add a CommandField (if needed) and set its ShowEditButton property to true. As we saw earlier, the CommandField contains a number of ShowXButton properties that indicate what series of buttons are displayed in the CommandField. Checking the Enable Editing checkbox adds the ShowEditButton property to the existing CommandField:
选择Enale Editing checkbox 会添加一个CommandField列并且它的ShowEditButton属性被设为true,这个CommandField包含一系列的ShowXButton属性,它们意味着是否显示相应的按钮。选择Editing Checkbox将在已有的CommandField上添加ShowEditButton属性
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

That’s all there is to adding rudimentary editing support. As Figure16 shows, the editing interface is rather crude – each BoundField whose ReadOnly property is set to false (the default) is rendered as a TextBox. This includes fields like CategoryID and SupplierID, which are keys to other tables
以上就是如何添加运行时的编辑功能,如下图所示,这种编辑界面是比较粗糙的,它只是把每个ReadOnlay属性为false的BoundField显示为TextBox,但是例如CategoryID and SupplierID,是其它表的键。

 

 


Figure 16: Clicking Chai’s Edit Button Displays the Row in “Edit Mode”

In addition to asking users to edit foreign key values directly, the editing interface’s interface is lacking in the following ways:
因为让用户直接编辑外键,这种用户界面有以下不足
• If the user enters a CategoryID or SupplierID that does not exist in the database, the UPDATE will violate a foreign key constraint, causing an exception to be raised.
• 如果用户输入了一个不存在的CategoryID or SupplierID,更新会引发异常。
• The editing interface doesn’t include any validation. If you don’t provide a required value (such as ProductName), or enter a string value where a numeric value is expected (such as entering “Too much!” into the UnitPrice textbox), an exception will be thrown. A future tutorial will examine how to add validation controls to the editing user interface.
• 编辑没有任何验证,如果没有提供一个正确的只例如要求输入数字的地方输入了字符串,会引发异常。以后的指南会讲解如何添加一个具有验证功能的编辑界面。
• Currently, all product fields that are not read-only must be included in the GridView. If we were to remove a field from the GridView, say UnitPrice, when updating the data the GridView would not set the UnitPrice UpdateParameters value, which would change the database record’s UnitPrice to a NULL value. Similarly, if a required field, such as ProductName, is removed from the GridView, the update will fail with the same “Column 'ProductName' does not allow nulls” exception mentioned above.
• 现在所有的product非只读字段都包括在GridView里。如果从GridView里删除了一个字段例如UnitPrice,更新是这个字段将会赋予null。如果这是一个比添字段。这回引发一个异常。
• The editing interface formatting leaves a lot to be desired. The UnitPrice is shown with four decimal points. Ideally the CategoryID and SupplierID values would contain DropDownLists that list the categories and suppliers in the system.
• 这个编辑界面还有许多不足。例如UnitPrice应该显示为4位的十进制小数。CategoryID and SupplierID应该显示为包含系统里所有categories and suppliers的DropDownList

These are all shortcomings that we’ll have to live with for now, but will be addressed in future tutorials.
以后的指南会讲解如何改进这些缺点

 

 

 

 

 

Inserting, Editing, and Deleting Data with the DetailsView
As we’ve seen in earlier tutorials, the DetailsView control displays one record at a time and, like the GridView, allows for editing and deleting of the currently displayed record. Both the end user’s experience with editing and deleting items from a DetailsView and the workflow from the ASP.NET side is identical to that of the GridView. Where the DetailsView differs from the GridView is that it also provides built-in inserting support.
在前面的指南中,我们看到DetailsView control 一次显示一个记录,也可以像GridView那样允许编辑和删除当前的记录,有经验的用户会发现DetailsView编辑和删除数据与GridView基本一致。只是DetailsView允许添加数据
To demonstrate the data modification capabilities of the GridView, start by adding a DetailsView to the Basics.aspx page above the existing GridView and bind it to the existing ObjectDataSource through the DetailsView’s smart tag. Next, clear out the DetailsView’s Height and Width properties, and check the Enable Paging option from the smart tag. To enable editing, inserting, and deleting support, simply check the Enable Editing, Enable Inserting, and Enable Deleting checkboxes in the smart tag.
我们在Baseics.aspx里加一个DetailsView并通过智能标记把它与现有的ObjectDataSource绑定,接着清除width和height属性,选择Enable Paging(允许分页),Enable Editing(允许编辑),Enable Inserting(允许插入),Enable Deleting(允许删除),如下图所示。
Figure 17: Configure the DetailsView to Support Editing, Inserting, and Deleting

As with the GridView, adding editing, inserting, or deleting support adds a CommandField to the DetailsView, as the following declarative syntax shows:
像GridView一样,添加了编辑、删除、插入功能后,会向它添加一个CommandField,页面代码如下。
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True" EnableViewState="False">
    <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>

Note that for the DetailsView the CommandField appears at the end of the Columns collection by default. Since the DetailsView’s fields are rendered as rows, the CommandField appears as a row with Insert, Edit, and Delete buttons at the bottom of the DetailsView.
注意DetailsView的CommandField默认显示在底部,每个字段显示为一行,CommandField显示为DetailsView底部的带有Insert、Edit、Delete按钮的一行,

 

Figure 18: Configure the DetailsView to Support Editing, Inserting, and Deleting

Clicking on the Delete button starts the same sequence of events as with the GridView: a postback; followed by the DetailsView populating its ObjectDataSource’s DeleteParameters based on the DataKeyNames values; and completed with a call its ObjectDataSource’s Delete() method, which actually removes the product from the database. Editing in the DetailsView also works in a fashion identical to that of the GridView.
点击Delete button会和GridView产生同样次序的事件:会送;接着把DataKeyNames字段的值赋给ObjectDataSourc的 DeleteParameters;调用ObjectDataSource的Delete()方法,完成数据库的删除。Editing也同GridView一样。
For inserting, the end user is presented with a New button that, when clicked, renders the DetailsView in “insert mode.” With “insert mode” the New button is replaced by Insert and Cancel buttons and only those BoundFields whose InsertVisible property is set to true (the default) are displayed. Those data fields identified as auto-increment fields, such as ProductID, have their InsertVisible property set to false when binding the DetailsView to the data source through the smart tag.
用户点击New button ,DetailsView 切换到 “insert mode”,在“insert mode”下“New button”被“insert button”和 “cancel button”替换,还有InsertVisible属性为true的BoundFields会显示出来,标识自增字段比如ProductId的InsertVisible 属性被是设为fase
When binding a data source to a DetailsView through the smart tag, Visual Studio sets the InsertVisible property to false only for auto-increment fields. Read-only fields, like CategoryName and SupplierName, will be displayed in the “insert mode” user interface unless their InsertVisible property is explicitly set to false. Take a moment to set these two fields’ InsertVisible properties to false, either through the DetailsView’s declarative syntax or through the Edit Fields link in the smart tag. Figure 19 shows setting the InsertVisible properties to false by clicking on the Edit Fields link.
VisualStdio在通过智能标记给DetailsView绑定数据源是只把自增列的InsertVisible属性设为false,具有ReadOnly属性的字段(例如:CategoryName and SupplierName)在“insert mode”一样会显示出来除非它们的InsertVisible 属性设为false,我们可以在页面源程序设置,也可以通过DetailsView的智能标记的Edit Fields来设定。

 

 

Figure 19: Northwind Traders Now Offers Acme Tea

After setting the InsertVisible properties, view the Basics.aspx page in a browser and click the New button. Figure 20 shows the DetailsView when adding a new beverage, Acme Tea, to our product line.
设置好InsertVisible属性,点击“New button”,就如Figure 20 所示,接着我们向产品表添加一个饮料,Acm Tea

 


Figure 20: Northwind Traders Now Offers Acme Tea

After entering the details for Acme Tea and clicking the Insert button, a postback ensues and the new record is added to the Products database table. Since this DetailsView lists the products in order with which they exist in the database table, we must page to the last product in order to see the new product.
输入完毕,点击Insert button,通过会送一个新的记录添加到Products数据库表里,我们在页面上翻倒最后一页就可以看到

 

 

 

 

 

 

 

 

 

 

 

Figure 21: Details for Acme Tea

Note: The DetailsView’s CurrentMode property indicates the interface being displayed and can be one of the following values: Edit, Insert, or ReadOnly. The DefaultMode property indicates the mode the DetailsView returns to after an edit or insert has been completed and is useful for displaying a DetailsView that is permanently in edit or insert mode.
注意:CurrentMode属性说明当前数据输入模式,它有以下几个模式:Edit,Insert,或者ReadOnlay。DefaultMode属性说明用户修改插入后DetailsView用户输入模式
The point and click inserting and editing capabilities of the DetailsView suffer from the same limitations as the GridView: the user must enter existing CategoryID and SupplierID values through a textbox; the interface lacks any validation logic; all product fields that do not allow NULL values or don’t have a default value specified at the database level must be included in the inserting interface, and so on.
The techniques we will examine for extending and enhancing the GridView’s editing interface in future articles can be applied to the DetailsView control’s editing and inserting interfaces as well.
本节只是泛泛的说明如何用DetailsView编辑插入数据,同GridView说明一样,有这样那样的不足,将来的指南里会教你如何解决这个问题


Using the FormView for a More Flexible Data Modification User Interface
The FormView offers built-in support for inserting, editing, and deleting data, but because it uses templates instead of fields there’s no place to add the BoundFields or the CommandField used by the GridView and DetailsView controls to provide the data modification interface. Instead, this interface – the Web controls for collecting user input when adding a new item or editing an existing one along with the New, Edit, Delete, Insert, Update, and Cancel buttons – must be added manually to the appropriate templates. Fortunately, Visual Studio will automatically create the needed interface when binding the FormView to a data source through the drop-down list in its smart tag.
FromView提供了内置的inserting,editing,deleteing数据的功能,但因为它用templates(模版)代替fields(字段),它不像GridView 和DetailsView那样通过添加BoundFields 和Commandfield 来实现数据的修改界面。它编辑数据需要通过手动添加适当的模版,幸运的是Vistual Stdio会替我们做大部分工作
To illustrate these techniques, start by adding a FormView to the Basics.aspx page and, from the FormView’s smart tag, bind it to the ObjectDataSource already created. This will generate an EditItemTemplate, InsertItemTemplate, and ItemTemplate for the FormView with TextBox Web controls for collecting the user’s input and Button Web controls for the New, Edit, Delete, Insert, Update, and Cancel buttons. Additionally, the FormView’s DataKeyNames property is set to the primary key field (ProductID) of the object returned by the ObjectDataSource. Lastly, check the Enable Paging option in the FormView’s smart tag.
为了说明这些技术,现在我们向Basics.aspx上添加一个FormView。在通过智能标记把ObjectDataSourc与它绑定。建立一个EditItemTemplate和InsertItemTemplate,FormView的ItemTemplate里有TextBox来采集用户的输入,还有几个button ( New, Edit, Delete, Insert , UpDate ,  Cancel)。FromView的DataKeyName属性被设置为从ObjectSource返回的主键值(这里是ProductId),最后在智能标记里选择“分页”。
The following shows the declarative markup for the FormView’s ItemTemplate after the FormView has been bound to the ObjectDataSource. By default, each non-Boolean value product field is bound to the Text property of a Label Web control while each Boolean value field (Discontinued) is bound to the Checked property of a disabled CheckBox Web control. In order for the New, Edit, and Delete buttons to trigger certain FormView behavior when clicked, it is imperative that their CommandName values be set to New, Edit, and Delete, respectively.
下面是FormView 的ItemTemplate绑定后的代码,非布尔字段的值被榜定到一个Label上,布尔值绑定到disabled状态的CheckBox。Edit,Delete 按钮点击会引发会送。并且分别的付给不同的CommandName值( New , Edit , Delete )
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True" EnableViewState="False">
    <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>

Figure 22 shows the FormView’s ItemTemplate when viewed through a browser. Each product field is listed with the New, Edit, and Delete buttons at the bottom.
Figure22 显示了通过游览器看到的结果,它列出了每个Product字段,New, Edit, Delete按钮在下面呈现出来。

 


Figure 22: The Defaut FormView ItemTemplate Lists Each Product Field Along with New, Edit, and Delete Buttons

Like with the GridView and DetailsView, clicking the Delete button – or any Button, LinkButton, or ImageButton whose CommandName property is set to Delete – causes a postback, populates the ObjectDataSource’s DeleteParameters based on the FormView’s DataKeyNames value, and invokes the ObjectDataSource’s Delete() method.
像GridView和DetailsView一样,点击Delete button,CommandName属性被设为Delete,并引发会送,ObjectDataSource的DeleteParameters 被设为FormView的DataKeyName字段的值,接着调用了ObjectDataSource的Delete()方法。

 When the Edit button is clicked a postback ensues and the data is rebound to the EditItemTemplate, which is responsible for rendering the editing interface. This interface includes the Web controls for editing data along with the Update and Cancel buttons. The default EditItemTemplate generated by Visual Studio contains a Label for any auto-increment fields (ProductID), a TextBox for each non-Boolean value field, and a CheckBox for each Boolean value field. This behavior is very similar to the auto-generated BoundFields in the GridView and DetailsView controls.
当Edit button被点击过程是这样的,页面回送,重新绑定数据到EditItemTemplate,控件切换到编辑状态。Edit button 被 Update button 和 Cancel button 替换,Visual Studio生成的默认的EditItemTemplate,自增字段被呈现为label,非布尔字段呈现为TextBox,布尔字段呈现为CheckBox,这些同GridView和DetailsView一样简单。
Note: One small issue with the FormView’s auto-generation of the EditItemTemplate is that it renders TextBox Web controls for those fields that are read-only, such as CategoryName and SupplierName. We’ll see how to account for this shortly.
    注意:一个小问题,FormView自动生成的EditItemTemplate会把read-only字段在编辑时也呈现为TextBox(比如:CategoryName and SupplierName),即刻我们就来说明如何处理它。
The TextBox controls in the EditItemTemplate have their Text property bound to the value of their corresponding data field using two-way databinding. Two-way databinding, denoted by <%# Bind("dataField") %>, performs databinding both when binding data to the template and when populating the ObjectDataSource’s parameters for inserting or editing records. That is, when the user clicks the Edit button from the ItemTemplate, the Bind() method returns the specified data field value. After the user makes their changes and clicks Update, the values posted back that correspond to the data fields specified using Bind() are applied to the ObjectDataSource’s UpdateParameters. Alternatively, one-way databinding, denoted by <%# Eval("dataField") %>, only retrieves the data field values when binding data to the template and does not return the user-entered values to the data source’s parameters on postback.
EditItemTemplate里TextBox的Text属性可以使用两路方式和相应的字段值绑定,使用<%#Bind(“dataField”)%>,不仅在获取数据时绑定,并且在点击Update button,也使用Bind()方法把用户修改的数据传给UpdateParameters,另外一种,一路绑定。<%#Eval(“dataField”)%>,仅仅在绑定是返回数据给模版,不会送用户修改的数据给数据源的参数。
The following declarative markup shows the FormView’s EditItemTemplate. Note that the Bind() method is used in the databinding syntax here and that the Update and Cancel Button Web controls have their CommandName properties set accordingly.
 下面代码显示FromView的EditItemTemplate,注意这里使用了Bind()语法,还有Update和Cancel button 正确的CommandName属性
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True" EnableViewState="False">
    <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>

Our EditItemTemplate, at this point, will cause an exception to be thrown if we attempt to use it. The problem is that the CategoryName and SupplierName fields are rendered as TextBox Web controls in the EditItemTemplate. We either need to change these TextBoxes to Labels or remove them altogether. Let’s simply delete them entirely from the EditItemTemplate.
如果我们使用现在这个EditItemTemplate ,点击 会引发一个异常,这是因为CategoryName and SupplierName 字段被呈现为TextBox控件,我需要把它改为Label或者移除它们,现在我们把它们从EditItemTemplate里删掉。
Figure 23 shows the FormView in a browser after the Edit button has been clicked for Chai. Note that the SupplierName and CategoryName fields shown in the ItemTemplate are no longer present, as we just removed them from the EditItemTemplate. When the Update button is clicked the FormView proceeds through the same sequence of steps as the GridView and DetailsView controls.
Figure23显示了游览器下,点击ProductName 为Chai 数据的Edit Button 的效果,这时SupplierName and CategoryName字段已经不存在。点击UpDate button会执行与GridView和DetailsView控件相同步骤。

 


Figure 23: By Default the EditItemTemplate Shows Each Editable Product Field as a TextBox or CheckBox

When the Insert button is clicked the FormView’s ItemTemplate a postback ensues. However, no data is bound to the FormView because a new record is being added. The InsertItemTemplate interface includes the Web controls for adding a new record along with the Insert and Cancel buttons. The default InsertItemTemplate generated by Visual Studio contains a TextBox for each non-Boolean value field and a CheckBox for each Boolean value field, similar to the auto-generated EditItemTemplate’s interface. The TextBox controls have their Text property bound to the value of their corresponding data field using two-way databinding.
点击FormView的ItemTemplate的insert button 会引发会送,然而没有数据绑定到FromView,因为这是添加新数据。插入界面包括了insert button  和 cancel button ,vs建立的默认InsertItemTemplate把每个非布尔字段绑定到TextBox,布尔字段绑定到CheckBox,如同EditItemTemplate,也使用双路绑定。

The following declarative markup shows the FormView’s InsertItemTemplate. Note that the Bind() method is used in the databinding syntax here and that the Insert and Cancel Button Web controls have their CommandName properties set accordingly.
下面是具体FormView  InsertItemTemplate的代码,注意它在绑定代码使用了Bind()方法,并且Insert button 和 Cancel button 各自设定CommandName属性
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True" EnableViewState="False">
    <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>

There’s a subtlety(微妙,精明) with the FormView’s auto-generation of the InsertItemTemplate. Specifically(特定,明确), the TextBox Web controls are created even for those fields that are read-only, such as CategoryName and SupplierName. Like with the EditItemTemplate, we need to remove these TextBoxes from the InsertItemTemplate.
只读字段也会被建立TextBox控件,比如CategoryName and SupplierName,我们需要从InsertItemTemplate删除这些。
Figure 24 shows the FormView in a browser when adding a new product, Acme Coffee. Note that the SupplierName and CategoryName fields shown in the ItemTemplate are no longer present, as we just removed them. When the Insert button is clicked the FormView proceeds through the same sequence of steps as the DetailsView control, adding a new record to the Products table. Figure 25 shows Acme Coffee product’s details in the FormView after it has been inserted.
Figure24 显示了用户添加了一个新的product(Acme Coffee)的页面,这里SupplierName and CategoryName字段已经不显示了,因为我们刚刚删除它们。点击Insert button 会发生和DetailsView控件插入新数据时的同样步骤,Figure25 显示新插入的数据详细信息。

 

 

 

 

Figure 24: The InsertItemTemplate Dictates the FormView’s Inserting Interface

 

 

 

 

 

 


 
Figure 25: The Details for New Product, Acme Coffee, are Displayed in the FormView

By separating out the read-only, editing, and inserting interfaces into three separate templates, the FormView allows for a finer degree of control over these interfaces than the DetailsView and GridView.
FromView允许比DetailsView和GridView更精细的控制。
Note: Like the DetailsView, the FormView’s CurrentMode property indicates the interface being displayed and its DefaultMode property indicates the mode the FormView returns to after an edit or insert has been completed.
注意:如同DetailsView,FormView’s的CurrentMode属性标志何种界面显示出来,DefaultMode属性标志FormView从edit或者Insert操作返回后显示何种模式。


Summary
In this tutorial we examined the basics of inserting, editing, and deleting data using the GridView, DetailsView, and FormView. All three of these controls provide some level of built-in data modification capabilities that can be utilized without writing a single line of code in the ASP.NET page thanks to the data Web controls and the ObjectDataSource. However, the simple point and click techniques render a fairly frail and naïve data modification user interface. To provide validation, inject programmatic values, gracefully handle exceptions, customize the user interface, and so on, we’ll need to rely on a bevy of techniques that will be discussed over the next several tutorials.

Happy Programming!

 

posted on 2006-08-01 16:01  倦怠  阅读(2063)  评论(0编辑  收藏  举报