<AlternatingItemStyle BackColor="#CCCCCC"></AlternatingItemStyle>
<HeaderStyle Font-Bold="True" HorizontalAlign="Center" ForeColor="White" BackColor="#094572"></HeaderStyle>
<Columns>
<asp:BoundColumn DataField="基金代码" ReadOnly="True" HeaderText="基金代码">
<HeaderStyle HorizontalAlign="Center" Width="20%"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="基金名称" ReadOnly="True" HeaderText="基金名称">
<HeaderStyle HorizontalAlign="Center" Width="20%"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundColumn>
<asp:TemplateColumn HeaderText="单位净值">
<HeaderStyle Width="20%"></HeaderStyle>
<HeaderTemplate>
<DIV align="center"><FONT face="宋体">单位净值</FONT></DIV>
</HeaderTemplate>
<ItemTemplate>
<INPUT id=dwjz type=text size=10 value='<%# DataBinder.Eval(Container.DataItem, "单位净值") %>' name=dwjz runat="server">
<asp:RegularExpressionValidator id="regulardwjz" Runat="server" Display="Dynamic" ControlToValidate="dwjz" ValidationExpression="(^[0-9]{1}\.[0-9]{1,4}$)|(^[0-9]{1}$)"> *</asp:RegularExpressionValidator>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="累计净值">
<HeaderStyle Width="20%"></HeaderStyle>
<HeaderTemplate>
<DIV align="center"><FONT face="宋体">累计净值</FONT></DIV>
</HeaderTemplate>
<ItemTemplate>
<INPUT id=ljjz type=text size=10 value='<%# DataBinder.Eval(Container.DataItem, "累计净值") %>' name=ljjz runat="server">
<asp:RegularExpressionValidator id="Regularljjz" Runat="server" Display="Dynamic" ControlToValidate="ljjz" ValidationExpression="(^[0-9]{1}\.[0-9]{1,4}$)|(^[0-9]{1}$)"> *</asp:RegularExpressionValidator>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="未经审计的单位拟分配收益">
<HeaderStyle Width="20%"></HeaderStyle>
<HeaderTemplate>
<DIV align="center"><FONT face="宋体">未经审计的单<BR>位拟分配收益</FONT></DIV>
</HeaderTemplate>
<ItemTemplate>
<INPUT id=wjshddwnfpsy type=text size=10 value='<%# DataBinder.Eval(Container.DataItem, "未经审计的单位拟分配收益") %>' name=wjshddwnfpsy runat="server">
<asp:RegularExpressionValidator id="Regularwjshddwnfpsy" Runat="server" Display="Dynamic" ControlToValidate="wjshddwnfpsy" ValidationExpression="(^[0-9]{1}\.[0-9]{1,4}$)|(^[0-9]{1}$)"> *</asp:RegularExpressionValidator>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:datagrid>
<script language="C#" runat="server">
public class weekreport : System.Web.UI.Page
{
config applicationconfig = new config();
protected System.Web.UI.WebControls.DataGrid DataGrid1;
protected System.Web.UI.HtmlControls.HtmlInputText Text1;
protected System.Web.UI.HtmlControls.HtmlInputText Text2;
protected System.Web.UI.HtmlControls.HtmlInputText Text3;
protected System.Web.UI.HtmlControls.HtmlInputText Text4;
protected System.Web.UI.HtmlControls.HtmlSelect Select1;
protected System.Web.UI.WebControls.Button btnSave;
protected System.Web.UI.HtmlControls.HtmlInputButton Submit1;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
if(!Page.IsPostBack)
{
PageDataBind();
}
}
public void PageDataBind()
{
string dbsql = "****************";
applicationconfig.connopen();
SqlDataAdapter dbcommand = new SqlDataAdapter(dbsql, applicationconfig.conn);
DataSet dbds = new DataSet();
dbcommand.Fill(dbds,"基金周报列表");
DataGrid1.DataSource = dbds.Tables["基金周报列表"].DefaultView;
DataGrid1.DataBind();
applicationconfig.connclose();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void btnSave_Click(object sender, System.EventArgs e)
{
}
}
</script>
6 个解决方案
#1
下面的是update的例子,其他类似
private void dgdTeacher_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string[] strFields;
strFields=new string[6];
//得到关键字
strFields[0]=dgdTeacher.DataKeys[e.Item.ItemIndex].ToString();
//将datagrid行中各单元的值赋给数组
for(int i=1;i<5;i++)
{
strFields[i]=((TextBox)e.Item.Cells[i].Controls[0]).Text ;
}
//更新数据库,返回影响的行数
//1=更新成功,其他=更新失败
intAffectedRows=trainDataBus.Update_T_CRM_Teacher(strFields);
//退出更新模式,重新绑定数据
dgdTeacher.EditItemIndex=-1;
//重新绑定datagrid
GridBind();
}
private void dgdTeacher_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string[] strFields;
strFields=new string[6];
//得到关键字
strFields[0]=dgdTeacher.DataKeys[e.Item.ItemIndex].ToString();
//将datagrid行中各单元的值赋给数组
for(int i=1;i<5;i++)
{
strFields[i]=((TextBox)e.Item.Cells[i].Controls[0]).Text ;
}
//更新数据库,返回影响的行数
//1=更新成功,其他=更新失败
intAffectedRows=trainDataBus.Update_T_CRM_Teacher(strFields);
//退出更新模式,重新绑定数据
dgdTeacher.EditItemIndex=-1;
//重新绑定datagrid
GridBind();
}
#2
try something like
for (int i=0; i < DataGrid1.Items.Count;i++)
{
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[2].FindControl("dwjz");
string sValue = tb.Value;
HtmlInputText tb2 = (HtmlInputText)DataGrid1.Items[i].Cells[3].FindControl("ljjz");
string sValue2 = tb2.Value;
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[4].FindControl("wjshddwnfpsy");
string sValue3 = tb3.Value;
//...update the database
}
for (int i=0; i < DataGrid1.Items.Count;i++)
{
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[2].FindControl("dwjz");
string sValue = tb.Value;
HtmlInputText tb2 = (HtmlInputText)DataGrid1.Items[i].Cells[3].FindControl("ljjz");
string sValue2 = tb2.Value;
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[4].FindControl("wjshddwnfpsy");
string sValue3 = tb3.Value;
//...update the database
}
#3
Visual Basic 和 Visual C# 概念
演练:使用 DataGrid Web 控件读取和写入数据请参见
演练:在 Web 窗体页中显示数据 | 演练:在 Web 窗体页中创建只读数据访问 | 演练:创建分布式应用程序 | 演练:在 Web 窗体中使用数据库更新查询更新数据 | 演练:验证 Web 窗体页中的用户输入
Web 窗体数据绑定的结构便于在页控件中显示数据。但是,数据绑定不是双向的,也就是说,数据绑定从数据源读取数据但不对其进行更新。更新比显示数据更复杂,因为大多数 Web 窗体页不需要将数据写回源,所以 Web 窗体数据绑定通过不包括更新代码将页大小和页处理保持在最精简的程度。
当然,有时候您要创建更新数据的 Web 窗体页。本演练阐释完成该目的的一种方式。它说明了如何使用 DataGrid 控件显示数据,允许用户对其进行编辑,然后将更改的数据发送回源。
当该页运行时,它看起来类似于下面这样:
若要完成本演练,您需要:
访问带有 Northwind SQL Server 示例数据库的服务器。
充足的权限,以便在 Web 服务器所在的计算机上创建 ASP.NET Web 应用程序项目。
演练被分成若干较小的部分:
创建 Web 窗体页。
添加必要的数据组件。
添加显示数据的 DataGrid 控件。
添加从数据库读取数据并将网格绑定到数据的代码。
配置 DataGrid 控件以允许用户编辑数据。
添加更新数据的代码。
创建项目和窗体
第一步是创建 Web 应用程序和 Web 窗体页。
创建项目和窗体
在“文件”菜单上指向“新建”,然后单击“项目”。
在“新建项目”对话框中,请执行以下操作:
在“项目类型”窗格中选择“Visual Basic 项目”或“Visual C# 项目”。
在“模板”窗格中选择“ASP.NET Web 应用程序”。
在“位置”框中,为您的应用程序输入完整的 URL(包含 http://、服务器名称和项目名称)。Web 服务器上必须安装 IIS 5 版(或更高版本)和 .NET 框架。如果计算机上已安装 IIS,可以为服务器指定 http://localhost。
当单击“确定”时,将在您指定的 Web 服务器的根处创建新的 Web 窗体项目。此外,名为 WebForm1.aspx 的新 Web 窗体页将显示在“设计”视图中 Web 窗体设计器上。
提示 如果在创建 Web 应用程序项目方面有困难,请参阅“Web 访问失败”对话框。
创建和配置数据集
在 Web 窗体页中,有多种访问数据的方法选择。一种方法是使用数据集,它是内存中的数据缓存。另外,您可以使用执行 SQL 语句或存储过程的数据命令直接访问数据库。一般情况下,使用数据集便于更新数据,这也正是您将在本演练中使用的方法。有关更多信息,请参阅 Web 数据访问策略建议。
您不直接将数据集添加到页。相反,您将执行下列一组步骤:
使用向导创建数据适配器。该适配器包含用于读取和写入数据库信息的 SQL 语句。该向导帮助您定义所需的 SQL 语句。如有必要,该向导还创建与数据库的连接。
生成数据集架构。在本过程中,您将让 Visual Studio 基于您正在访问的表和列创建一个新的数据集类。在生成数据集类时,您还将向窗体中添加该类的一个实例。
遵循本节中的所有过程很重要。否则,您的页将不具有在本演练的随后部分中将使用的数据集。
有关数据适配器的概述,请参阅数据适配器介绍。有关数据集的概述,请参阅数据集介绍。
配置数据连接和数据适配器
若要开始,请创建一个包含稍后用于填充数据集的 SQL 语句的数据适配器。作为此过程的一部分,定义连接以访问数据库。使用向导配置数据适配器,该向导使创建数据访问所需的 SQL 语句变得容易。
注意 向导完成后,您必须继续下一部分操作,以便生成数据集并完成该页的数据访问部分。
创建数据连接和数据适配器
从工具箱的“数据”选项卡中,将一个 SqlDataAdapter 对象拖到页上。
注意 如果您未使用 SQL Server,则应使用类型 OleDbDataAdapter 的适配器,它提供到任何与 OLE DB 兼容的数据源的访问。
“数据适配器配置向导”启动,它将帮助您创建连接和适配器。
在该向导中,执行下列操作:
在第二个窗格中,创建或选择一个指向 SQL Server Northwind 数据库的连接。有关访问数据库的信息,请与您的数据库管理员联系。
注意 您需要在所使用的 SQL Server 上具有适当的读/写权限。建议在创建连接时指定 Windows 集成安全性。或者,可以指定用户名和密码并将该信息与此连接保存在一起,但这样做会危及安全性。有关更多信息,请参阅数据库安全性。
在第三个窗格中,指定您要使用 SQL 语句访问数据库。
在第四个窗格中创建以下 SQL 语句:
SELECT CategoryID, CategoryName, Description
FROM Categories
有关如何生成 SQL 语句的帮助,请单击“查询生成器”启动“查询生成器”对话框。
注意 在本演练中,将使用类别表中的所有行来填充数据集。在成品应用程序中,通常通过创建只返回所需列和行的查询来优化数据访问。有关示例,请参阅演练:使用参数化查询在 Windows 窗体中显示数据。
单击“完成”。
向导创建一个连接(SqlConnection1 或 sqlConnection1),它包含有关如何访问数据库的信息。您还将具有包含一个查询的数据适配器(SqlDataAdapter1 或 sqlDataAdapter1),该查询定义所要访问数据库中的表和列。
向导完成后,您需要基于在该过程中创建的 SQL 查询生成数据集。有关详细信息,请参阅下一节。
创建数据集
建立连接到数据库的方法并指定所需的信息(通过数据适配器中的 SQL 命令)后,可以让 Visual Studio 创建数据集。Visual Studio 可以基于您为数据适配器指定的查询自动生成数据集。数据集是基于相应架构(.xsd 文件)的 DataSet 类的一个实例,该架构描述类的元素(表、列和约束)。有关数据集与架构之间关系的详细信息,请参阅 ADO.NET 数据访问介绍。
生成数据集
从“数据”菜单中选择“生成数据集”。
提示 如果“生成数据集”命令未启用,则单击该页;页必须具有焦点,该命令才会出现。
“生成数据集”对话框出现。
选择“新建”选项,将该数据集命名为 dsCategories。
在“选择要添加到数据集中的表”下面的列表中,确保选择了 Categories 表。
确保“将此数据集添加到设计器”已选中,然后单击“确定”。
Visual Studio 生成某类型化数据集类 (dsCategories) 和定义该数据集的架构。您将在解决方案资源管理器中看到新的架构 (dsCategories.xsd)。
提示 在解决方案资源管理器中,单击“显示所有文件”工具栏按钮以查看架构文件的相关 .vb 或 .cs 文件,该文件包含定义新数据集类的代码。
最后,Visual Studio 将新数据集类 (dsCategories1) 的实例添加到页上。
此刻,为执行从数据库获取信息并转移到数据集的操作所需的全部设置均已完成。
添加显示数据的 DataGrid 控件
在本演练中,您将添加单个控件(DataGrid 控件),该控件可以同时显示数据集中的所有记录并允许您添加编辑记录的功能。
数据网格必须绑定到数据集才能显示数据。
向窗体添加绑定 DataGrid 控件
如果尚未进行该操作,请单击当前窗口顶部的选项卡切换到 Web 窗体设计器。
从工具箱的“Web 窗体”选项卡中,将一个 DataGrid 控件拖到窗体上。
选择该控件,按 F4 键显示“属性”窗口,在窗口的底部,单击“属性生成器”。
“DataGrid 属性”对话框出现。
在“常规”选项卡中,完成以下设置:属性 设置 说明
数据源 dsCategories1 将网格绑定到数据集。
数据成员 Categories 指定网格应该显示数据集的类别表中的数据
数据键字段 CategoryID 指定类别记录的主键是 CategoryID 列。这将允许您稍后确定更新数据集中的哪个记录。
单击“确定”关闭“DataGrid 属性”对话框。
如果您要更改网格的外观,请设置“字体”、“背景色”和其他属性。
提示 一种简单的设置网格外观的方法是单击“属性”窗口底部的“自动套用格式”,然后选择预定义的外观。
填充数据集并在 DataGrid 控件中显示数据
尽管网格被绑定到所创建的数据集,但是,数据集本身不会被自动填写。相反,您必须自己调用数据适配器方法来填充数据集。有关填充数据集的详细信息,请参阅数据集介绍。
即使在数据集被填充后,DataGrid 控件仍不会自动显示数据。您必须将网格显式绑定到它的数据源。有关更多信息,请参阅 Web 窗体页中的数据绑定介绍。
填充数据集并在 DataGrid 控件中显示数据
双击当前页,在代码编辑器中显示该页的类文件。
在 Page_Load 事件处理程序中,调用数据适配器的 Fill 方法并向其传递要填充的数据集:
' Visual Basic
SqlDataAdapter1.Fill(DsCategories1)
//C#
sqlDataAdapter1.Fill(dsCategories1);
调用 DataGrid 控件的 DataBind 方法,将该控件绑定到数据集。但是,您不想在页每次进行往返行程时都重新绑定控件,因为如果这样做,将丢失用户已在网格中进行的更改。因此,您应该只在以下这些情况下绑定网格:
第一次调用页时。
数据集更改时。
现在,您要在第一次调用页时绑定网格,这可以通过测试页的 IsPostBack 属性完成。在调用了适配器的 Fill 方法之后将代码添加到 Page_Load 事件处理程序。完整的处理程序看起来将类似于下面这样:
' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
SqlDataAdapter1.Fill(DsCategories1)
If Not IsPostBack Then
DataGrid1.DataBind()
End If
End Sub
// C#
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
sqlDataAdapter1.Fill(dsCategories1);
if (!IsPostBack)
{
DataGrid1.DataBind();
}
}
添加编辑数据的功能
按照配置,DataGrid 控件将显示 Categories 表中的信息。但您还希望用户可以
演练:使用 DataGrid Web 控件读取和写入数据请参见
演练:在 Web 窗体页中显示数据 | 演练:在 Web 窗体页中创建只读数据访问 | 演练:创建分布式应用程序 | 演练:在 Web 窗体中使用数据库更新查询更新数据 | 演练:验证 Web 窗体页中的用户输入
Web 窗体数据绑定的结构便于在页控件中显示数据。但是,数据绑定不是双向的,也就是说,数据绑定从数据源读取数据但不对其进行更新。更新比显示数据更复杂,因为大多数 Web 窗体页不需要将数据写回源,所以 Web 窗体数据绑定通过不包括更新代码将页大小和页处理保持在最精简的程度。
当然,有时候您要创建更新数据的 Web 窗体页。本演练阐释完成该目的的一种方式。它说明了如何使用 DataGrid 控件显示数据,允许用户对其进行编辑,然后将更改的数据发送回源。
当该页运行时,它看起来类似于下面这样:
若要完成本演练,您需要:
访问带有 Northwind SQL Server 示例数据库的服务器。
充足的权限,以便在 Web 服务器所在的计算机上创建 ASP.NET Web 应用程序项目。
演练被分成若干较小的部分:
创建 Web 窗体页。
添加必要的数据组件。
添加显示数据的 DataGrid 控件。
添加从数据库读取数据并将网格绑定到数据的代码。
配置 DataGrid 控件以允许用户编辑数据。
添加更新数据的代码。
创建项目和窗体
第一步是创建 Web 应用程序和 Web 窗体页。
创建项目和窗体
在“文件”菜单上指向“新建”,然后单击“项目”。
在“新建项目”对话框中,请执行以下操作:
在“项目类型”窗格中选择“Visual Basic 项目”或“Visual C# 项目”。
在“模板”窗格中选择“ASP.NET Web 应用程序”。
在“位置”框中,为您的应用程序输入完整的 URL(包含 http://、服务器名称和项目名称)。Web 服务器上必须安装 IIS 5 版(或更高版本)和 .NET 框架。如果计算机上已安装 IIS,可以为服务器指定 http://localhost。
当单击“确定”时,将在您指定的 Web 服务器的根处创建新的 Web 窗体项目。此外,名为 WebForm1.aspx 的新 Web 窗体页将显示在“设计”视图中 Web 窗体设计器上。
提示 如果在创建 Web 应用程序项目方面有困难,请参阅“Web 访问失败”对话框。
创建和配置数据集
在 Web 窗体页中,有多种访问数据的方法选择。一种方法是使用数据集,它是内存中的数据缓存。另外,您可以使用执行 SQL 语句或存储过程的数据命令直接访问数据库。一般情况下,使用数据集便于更新数据,这也正是您将在本演练中使用的方法。有关更多信息,请参阅 Web 数据访问策略建议。
您不直接将数据集添加到页。相反,您将执行下列一组步骤:
使用向导创建数据适配器。该适配器包含用于读取和写入数据库信息的 SQL 语句。该向导帮助您定义所需的 SQL 语句。如有必要,该向导还创建与数据库的连接。
生成数据集架构。在本过程中,您将让 Visual Studio 基于您正在访问的表和列创建一个新的数据集类。在生成数据集类时,您还将向窗体中添加该类的一个实例。
遵循本节中的所有过程很重要。否则,您的页将不具有在本演练的随后部分中将使用的数据集。
有关数据适配器的概述,请参阅数据适配器介绍。有关数据集的概述,请参阅数据集介绍。
配置数据连接和数据适配器
若要开始,请创建一个包含稍后用于填充数据集的 SQL 语句的数据适配器。作为此过程的一部分,定义连接以访问数据库。使用向导配置数据适配器,该向导使创建数据访问所需的 SQL 语句变得容易。
注意 向导完成后,您必须继续下一部分操作,以便生成数据集并完成该页的数据访问部分。
创建数据连接和数据适配器
从工具箱的“数据”选项卡中,将一个 SqlDataAdapter 对象拖到页上。
注意 如果您未使用 SQL Server,则应使用类型 OleDbDataAdapter 的适配器,它提供到任何与 OLE DB 兼容的数据源的访问。
“数据适配器配置向导”启动,它将帮助您创建连接和适配器。
在该向导中,执行下列操作:
在第二个窗格中,创建或选择一个指向 SQL Server Northwind 数据库的连接。有关访问数据库的信息,请与您的数据库管理员联系。
注意 您需要在所使用的 SQL Server 上具有适当的读/写权限。建议在创建连接时指定 Windows 集成安全性。或者,可以指定用户名和密码并将该信息与此连接保存在一起,但这样做会危及安全性。有关更多信息,请参阅数据库安全性。
在第三个窗格中,指定您要使用 SQL 语句访问数据库。
在第四个窗格中创建以下 SQL 语句:
SELECT CategoryID, CategoryName, Description
FROM Categories
有关如何生成 SQL 语句的帮助,请单击“查询生成器”启动“查询生成器”对话框。
注意 在本演练中,将使用类别表中的所有行来填充数据集。在成品应用程序中,通常通过创建只返回所需列和行的查询来优化数据访问。有关示例,请参阅演练:使用参数化查询在 Windows 窗体中显示数据。
单击“完成”。
向导创建一个连接(SqlConnection1 或 sqlConnection1),它包含有关如何访问数据库的信息。您还将具有包含一个查询的数据适配器(SqlDataAdapter1 或 sqlDataAdapter1),该查询定义所要访问数据库中的表和列。
向导完成后,您需要基于在该过程中创建的 SQL 查询生成数据集。有关详细信息,请参阅下一节。
创建数据集
建立连接到数据库的方法并指定所需的信息(通过数据适配器中的 SQL 命令)后,可以让 Visual Studio 创建数据集。Visual Studio 可以基于您为数据适配器指定的查询自动生成数据集。数据集是基于相应架构(.xsd 文件)的 DataSet 类的一个实例,该架构描述类的元素(表、列和约束)。有关数据集与架构之间关系的详细信息,请参阅 ADO.NET 数据访问介绍。
生成数据集
从“数据”菜单中选择“生成数据集”。
提示 如果“生成数据集”命令未启用,则单击该页;页必须具有焦点,该命令才会出现。
“生成数据集”对话框出现。
选择“新建”选项,将该数据集命名为 dsCategories。
在“选择要添加到数据集中的表”下面的列表中,确保选择了 Categories 表。
确保“将此数据集添加到设计器”已选中,然后单击“确定”。
Visual Studio 生成某类型化数据集类 (dsCategories) 和定义该数据集的架构。您将在解决方案资源管理器中看到新的架构 (dsCategories.xsd)。
提示 在解决方案资源管理器中,单击“显示所有文件”工具栏按钮以查看架构文件的相关 .vb 或 .cs 文件,该文件包含定义新数据集类的代码。
最后,Visual Studio 将新数据集类 (dsCategories1) 的实例添加到页上。
此刻,为执行从数据库获取信息并转移到数据集的操作所需的全部设置均已完成。
添加显示数据的 DataGrid 控件
在本演练中,您将添加单个控件(DataGrid 控件),该控件可以同时显示数据集中的所有记录并允许您添加编辑记录的功能。
数据网格必须绑定到数据集才能显示数据。
向窗体添加绑定 DataGrid 控件
如果尚未进行该操作,请单击当前窗口顶部的选项卡切换到 Web 窗体设计器。
从工具箱的“Web 窗体”选项卡中,将一个 DataGrid 控件拖到窗体上。
选择该控件,按 F4 键显示“属性”窗口,在窗口的底部,单击“属性生成器”。
“DataGrid 属性”对话框出现。
在“常规”选项卡中,完成以下设置:属性 设置 说明
数据源 dsCategories1 将网格绑定到数据集。
数据成员 Categories 指定网格应该显示数据集的类别表中的数据
数据键字段 CategoryID 指定类别记录的主键是 CategoryID 列。这将允许您稍后确定更新数据集中的哪个记录。
单击“确定”关闭“DataGrid 属性”对话框。
如果您要更改网格的外观,请设置“字体”、“背景色”和其他属性。
提示 一种简单的设置网格外观的方法是单击“属性”窗口底部的“自动套用格式”,然后选择预定义的外观。
填充数据集并在 DataGrid 控件中显示数据
尽管网格被绑定到所创建的数据集,但是,数据集本身不会被自动填写。相反,您必须自己调用数据适配器方法来填充数据集。有关填充数据集的详细信息,请参阅数据集介绍。
即使在数据集被填充后,DataGrid 控件仍不会自动显示数据。您必须将网格显式绑定到它的数据源。有关更多信息,请参阅 Web 窗体页中的数据绑定介绍。
填充数据集并在 DataGrid 控件中显示数据
双击当前页,在代码编辑器中显示该页的类文件。
在 Page_Load 事件处理程序中,调用数据适配器的 Fill 方法并向其传递要填充的数据集:
' Visual Basic
SqlDataAdapter1.Fill(DsCategories1)
//C#
sqlDataAdapter1.Fill(dsCategories1);
调用 DataGrid 控件的 DataBind 方法,将该控件绑定到数据集。但是,您不想在页每次进行往返行程时都重新绑定控件,因为如果这样做,将丢失用户已在网格中进行的更改。因此,您应该只在以下这些情况下绑定网格:
第一次调用页时。
数据集更改时。
现在,您要在第一次调用页时绑定网格,这可以通过测试页的 IsPostBack 属性完成。在调用了适配器的 Fill 方法之后将代码添加到 Page_Load 事件处理程序。完整的处理程序看起来将类似于下面这样:
' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
SqlDataAdapter1.Fill(DsCategories1)
If Not IsPostBack Then
DataGrid1.DataBind()
End If
End Sub
// C#
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
sqlDataAdapter1.Fill(dsCategories1);
if (!IsPostBack)
{
DataGrid1.DataBind();
}
}
添加编辑数据的功能
按照配置,DataGrid 控件将显示 Categories 表中的信息。但您还希望用户可以
#4
创建 UpdateCommand 处理程序
(在 Visual Basic 中)如果尚未将其打开,则再次打开代码编辑器。
— 或 —
(在 Visual C# 中)在“设计”视图中,选择网格并按 F4 键打开“属性”窗口。
(在 Visual Basic 中)在代码编辑器上方的左侧下拉列表中选择“DataGrid1”。
— 或 —
(在 Visual C# 中)单击“属性”窗口顶部的“事件”按钮 ()。
(在 Visual Basic 中)在代码编辑器顶部右侧的下拉列表中选择“UpdateCommand”。
— 或 —
(在 Visual C# 中)双击网格中的“UpdateCommand”。
创建了一个 DataGrid1_UpdateCommand 事件处理程序。
从 DataGrid 控件进行更新的步骤
您将执行的操作的大纲如下:
确定 DataGrid 控件中哪一行(根据索引)已被更新。然后,从该网格行获取数据键,以便确定正在更新的行(根据 ID)。
从用户更新的网格行获取更改的值。
使用数据键值在数据集表中查找对应的行,然后将更改写入该行。此时,您已更新了数据集,但未更新数据库本身。
将更改从数据集发送到数据库。这执行将更改从数据集复制到数据库的 SQL 命令或存储过程。
刷新 DataGrid 控件的内容。
下面一节解释这些步骤中每一步的详细情况。如果愿意,您可以跳过这些解释,直接进入随后的代码。
从 DataGrid 控件进行更新
通过获取传入事件对象的行(Item 对象)的 ItemIndex 属性确定哪个 DataGrid 行已被更新。然后使用该索引值从网格的 DataKeys 集合中获取对应的值。
' Visual Basic
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString()
// C#
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
从 DataGrid 行中获取更改的值。若要完成该操作,请:
从传入事件对象的项的 Cells 集合中获取适当的单元格(从零开始的)。例如,网格中最左边一列为 Cells(0)。
对于每个单元格,获取其 Controls 集合,它包含显示在该单元格中的所有元素。
从该集合中获取第一个(并且只是第一个)控件,在本例中为 TextBox 控件。若要获取 TextBox,声明一个类型 TextBox 的局部变量,并将 Controls 集合中的对象分配给它。
获取 TextBox 控件的值(其 Text 属性)。
下面的示例显示如何执行这些步骤。
' Visual Basic
Dim categoryName, categoryDescription As String
Dim tb As TextBox
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
// C#
string categoryname;
string categoryDescription;
TextBox tb;
tb = (TextBox) e.Item.Cells[2].Controls[0];
categoryName = tb.Text;
tb = (TextBox) e.Item.Cells[3].Controls[0];
categoryDescription = tb.Text
在数据表中查找对应的行。类型化的 dsCategories 数据集包含一个特殊的 FindBy 方法(在本例中为 FindByCategoryID 方法),该方法通过行的主键定位行并返回一个对它的引用。创建类型化数据行的变量并调用该方法:
' Visual Basic
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
// C#
dsCategories.CategoriesRow r;
r = DsCategories1.Categories.FindByCategoryID(key);
通过更改您在第三步所在行中的值更新该行,如下面的示例所示:
' Visual Basic
r.CategoryName = categoryName
r.Description = categoryDescription
// C#
r.CategoryName = categoryName;
r.Description = categoryDescription;
通过调用数据适配器的 Update 方法将更改从数据集发送到数据库:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
DataGrid1.DataBind()
// C#
SqlDataAdapter1.Update(DsCategories1);
DataGrid1.DataBind();
将网格中的当前行切换出编辑模式。
' Visual Basic
DataGrid1.EditItemIndex = -1
// C#
DataGrid1.EditItemIndex = -1;
数据绑定 DataGrid 控件:
' Visual Basic
DataGrid1.DataBind()
// C#
DataGrid1.DataBind();
下面的代码显示完成的 UpdateCommand 事件处理程序是什么样的。复制该代码并将其粘贴到 Web 窗体页的类文件。
提示 一定要改写先前创建的主干事件处理程序,否则将有两个方法具有相同的名称和签名。
' Visual Basic
Private Sub DataGrid1_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.UpdateCommand
Dim categoryName, categoryDescription As String
' Gets the value of the key field of the row being updated
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString
' Gets get the value of the controls (textboxes) that the user
' updated. The DataGrid columns are exposed as the Cells collection.
' Each cell has a collection of controls. In this case, there is only one
' control in each cell -- a TextBox control. To get its value,
' you copy the TextBox to a local instance (which requires casting)
' and extract its Text property.
'
' The first column -- Cells(0) -- contains the Update and Cancel buttons.
Dim tb As TextBox
' Gets the value the TextBox control in the third column
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
' Gets the value the TextBox control in the fourth column
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
' Finds the row in the dataset table that matches the
' one the user updated in the grid. This example uses a
' special Find method defined for the typed dataset, which
' returns a reference to the row.
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
' Updates the dataset table.
r.CategoryName = categoryName
r.Description = categoryDescription
' Calls a SQL statement to update the database from the dataset
SqlDataAdapter1.Update(DsCategories1)
' Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1
' Refreshes the grid
DataGrid1.DataBind()
End Sub
// C#
private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string categoryName, categoryDescription;
// Gets the value of the key field of the row being updated
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
// Gets get the value of the controls (textboxes) that the user
// updated. The DataGrid columns are exposed as the Cells collection.
// Each cell has a collection of controls. In this case, there is only one
// control in each cell -- a TextBox control. To get its value,
// you copy the TextBox to a local instance (which requires casting)
// and extract its Text property.
//
// The first column -- Cells(0) -- contains the Update and Cancel buttons.
TextBox tb;
// Gets the value the TextBox control in the third column
tb = (TextBox)(e.Item.Cells[2].Controls[0]);
categoryName = tb.Text;
// Gets the value the TextBox control in the fourth column
tb = (TextBox)(e.Item.Cells[3].Controls[0]);
categoryDescription = tb.Text;
// Finds the row in the dataset table that matches the
// one the user updated in the grid. This example uses a
// special Find method defined for the typed dataset, which
// returns a reference to the row.
dsCategories.CategoriesRow r;
r = dsCategories1.Categories.FindByCategoryID(int.Parse(key));
// Updates the dataset table.
r.CategoryName = categoryName;
r.Description = categoryDescription;
// Calls a SQL statement to update the database from the dataset
sqlDataAdapter1.Update(dsCategories1);
// Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1;
// Refreshes the grid
DataGrid1.DataBind();
}
测试
现在您已完成所有操作。若要阐释网格如何工作并确保它正确更新数据,您应该对页进行测试。
(在 Visual Basic 中)如果尚未将其打开,则再次打开代码编辑器。
— 或 —
(在 Visual C# 中)在“设计”视图中,选择网格并按 F4 键打开“属性”窗口。
(在 Visual Basic 中)在代码编辑器上方的左侧下拉列表中选择“DataGrid1”。
— 或 —
(在 Visual C# 中)单击“属性”窗口顶部的“事件”按钮 ()。
(在 Visual Basic 中)在代码编辑器顶部右侧的下拉列表中选择“UpdateCommand”。
— 或 —
(在 Visual C# 中)双击网格中的“UpdateCommand”。
创建了一个 DataGrid1_UpdateCommand 事件处理程序。
从 DataGrid 控件进行更新的步骤
您将执行的操作的大纲如下:
确定 DataGrid 控件中哪一行(根据索引)已被更新。然后,从该网格行获取数据键,以便确定正在更新的行(根据 ID)。
从用户更新的网格行获取更改的值。
使用数据键值在数据集表中查找对应的行,然后将更改写入该行。此时,您已更新了数据集,但未更新数据库本身。
将更改从数据集发送到数据库。这执行将更改从数据集复制到数据库的 SQL 命令或存储过程。
刷新 DataGrid 控件的内容。
下面一节解释这些步骤中每一步的详细情况。如果愿意,您可以跳过这些解释,直接进入随后的代码。
从 DataGrid 控件进行更新
通过获取传入事件对象的行(Item 对象)的 ItemIndex 属性确定哪个 DataGrid 行已被更新。然后使用该索引值从网格的 DataKeys 集合中获取对应的值。
' Visual Basic
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString()
// C#
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
从 DataGrid 行中获取更改的值。若要完成该操作,请:
从传入事件对象的项的 Cells 集合中获取适当的单元格(从零开始的)。例如,网格中最左边一列为 Cells(0)。
对于每个单元格,获取其 Controls 集合,它包含显示在该单元格中的所有元素。
从该集合中获取第一个(并且只是第一个)控件,在本例中为 TextBox 控件。若要获取 TextBox,声明一个类型 TextBox 的局部变量,并将 Controls 集合中的对象分配给它。
获取 TextBox 控件的值(其 Text 属性)。
下面的示例显示如何执行这些步骤。
' Visual Basic
Dim categoryName, categoryDescription As String
Dim tb As TextBox
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
// C#
string categoryname;
string categoryDescription;
TextBox tb;
tb = (TextBox) e.Item.Cells[2].Controls[0];
categoryName = tb.Text;
tb = (TextBox) e.Item.Cells[3].Controls[0];
categoryDescription = tb.Text
在数据表中查找对应的行。类型化的 dsCategories 数据集包含一个特殊的 FindBy 方法(在本例中为 FindByCategoryID 方法),该方法通过行的主键定位行并返回一个对它的引用。创建类型化数据行的变量并调用该方法:
' Visual Basic
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
// C#
dsCategories.CategoriesRow r;
r = DsCategories1.Categories.FindByCategoryID(key);
通过更改您在第三步所在行中的值更新该行,如下面的示例所示:
' Visual Basic
r.CategoryName = categoryName
r.Description = categoryDescription
// C#
r.CategoryName = categoryName;
r.Description = categoryDescription;
通过调用数据适配器的 Update 方法将更改从数据集发送到数据库:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
DataGrid1.DataBind()
// C#
SqlDataAdapter1.Update(DsCategories1);
DataGrid1.DataBind();
将网格中的当前行切换出编辑模式。
' Visual Basic
DataGrid1.EditItemIndex = -1
// C#
DataGrid1.EditItemIndex = -1;
数据绑定 DataGrid 控件:
' Visual Basic
DataGrid1.DataBind()
// C#
DataGrid1.DataBind();
下面的代码显示完成的 UpdateCommand 事件处理程序是什么样的。复制该代码并将其粘贴到 Web 窗体页的类文件。
提示 一定要改写先前创建的主干事件处理程序,否则将有两个方法具有相同的名称和签名。
' Visual Basic
Private Sub DataGrid1_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.UpdateCommand
Dim categoryName, categoryDescription As String
' Gets the value of the key field of the row being updated
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString
' Gets get the value of the controls (textboxes) that the user
' updated. The DataGrid columns are exposed as the Cells collection.
' Each cell has a collection of controls. In this case, there is only one
' control in each cell -- a TextBox control. To get its value,
' you copy the TextBox to a local instance (which requires casting)
' and extract its Text property.
'
' The first column -- Cells(0) -- contains the Update and Cancel buttons.
Dim tb As TextBox
' Gets the value the TextBox control in the third column
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
' Gets the value the TextBox control in the fourth column
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
' Finds the row in the dataset table that matches the
' one the user updated in the grid. This example uses a
' special Find method defined for the typed dataset, which
' returns a reference to the row.
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
' Updates the dataset table.
r.CategoryName = categoryName
r.Description = categoryDescription
' Calls a SQL statement to update the database from the dataset
SqlDataAdapter1.Update(DsCategories1)
' Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1
' Refreshes the grid
DataGrid1.DataBind()
End Sub
// C#
private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string categoryName, categoryDescription;
// Gets the value of the key field of the row being updated
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
// Gets get the value of the controls (textboxes) that the user
// updated. The DataGrid columns are exposed as the Cells collection.
// Each cell has a collection of controls. In this case, there is only one
// control in each cell -- a TextBox control. To get its value,
// you copy the TextBox to a local instance (which requires casting)
// and extract its Text property.
//
// The first column -- Cells(0) -- contains the Update and Cancel buttons.
TextBox tb;
// Gets the value the TextBox control in the third column
tb = (TextBox)(e.Item.Cells[2].Controls[0]);
categoryName = tb.Text;
// Gets the value the TextBox control in the fourth column
tb = (TextBox)(e.Item.Cells[3].Controls[0]);
categoryDescription = tb.Text;
// Finds the row in the dataset table that matches the
// one the user updated in the grid. This example uses a
// special Find method defined for the typed dataset, which
// returns a reference to the row.
dsCategories.CategoriesRow r;
r = dsCategories1.Categories.FindByCategoryID(int.Parse(key));
// Updates the dataset table.
r.CategoryName = categoryName;
r.Description = categoryDescription;
// Calls a SQL statement to update the database from the dataset
sqlDataAdapter1.Update(dsCategories1);
// Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1;
// Refreshes the grid
DataGrid1.DataBind();
}
测试
现在您已完成所有操作。若要阐释网格如何工作并确保它正确更新数据,您应该对页进行测试。
#5
对页进行测试
在解决方案资源管理器中,右击 Web 窗体页并选择“生成并浏览”。
当前项目将被编译,Web 窗体页将显示在设计器的浏览器窗格中。
单击网格中任何一行的“编辑”链接,然后使用文本框编辑该行。
单击“更新”。
网格重新显示,并带有您的更改。如果检查数据库,您将看到已适当写入更改。
下一步
在本演练中,您使用 Web 窗体页上的 DataGrid 控件不仅仅是查看数据,而是要编辑数据。为了清楚起见,本演练跳过了一些在成品应用程序中要考虑的细节。您要对本演练中所学的内容有所加强的一些方面包括:
增强 DataGrid 控件的功能
本演练没有利用 DataGrid 控件的某些更高级的功能。您可以增强的方面包括:
通过选择特定的要显示的列、更改列标题等配置网格中的个别列。有关详细信息,请参阅向 DataGrid Web 服务器控件添加绑定列和指定 DataGrid Web 服务器控件中网格项的格式
允许用户删除行。有关详细信息,请参阅允许用户删除 DataGrid Web 服务器控件中的项。除了指定“删除”按钮之外,您需要添加代码以从数据集中移除记录。有关详细信息,请参阅删除数据集中的记录。
使用分页。在本例中,您只显示几条记录。但是,经常要显示更多的记录,如果是这样,允许网格以一次一页的方式显示信息是非常必要的。有关详细信息,请参阅 DataGrid Web 服务器控件中的分页行为。
缓存数据集
在本演练中,页每次到服务器的往返行程都会使数据集重新实例化并从数据库重新填充数据集。这种策略虽然实现起来非常简单,但是却会导致到数据库服务器不必要的通信量。
一种替代方法是在填充数据集和每次更改数据集之后将数据集存储起来。于是您可以在每次往返行程发生后恢复数据集,而不用重新读取数据库信息。存储数据集有多种方法,其中包括存储在会话状态(在服务器上)或视图状态(在客户端上,页中)。有关要使用哪种策略的详细信息,请参阅状态管理建议。
例如,如果您要在会话状态中存储数据集,则可能要在 Page_Load 事件处理程序中包括以下代码:
' Visual Basic
If Not Page.IsPostBack Then
If Session("mydatset") Is Nothing Then
SqlDataAdapter1.Fill(dsCategories1)
Session("mydataset") = dsCategories1
Else
dsCategories1 = CType(Session("mydatset"), dsCategories)
End If
DataGrid1.DataBind()
End If
// C#
if (! Page.IsPostBack)
{
if (Session["mydatset"] == null)
{
sqlDataAdapter1.Fill(dsCategories1);
Session["mydataset"] = dsCategories1;
}
else
{
dsCategories1 = (dsCategories)Session["mydatset"];
}
DataGrid1.DataBind();
}
请注意,如果要在会话状态或应用程序状态中存储数据集,则当将其取回时需要将其强制转换为适当的数据集类型。
每次数据集更改时,一定要刷新会话状态中该数据集的副本。例如,您可能要在 UpdateCommand 事件处理程序中紧接在更新数据库之后添加下面一行:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
Session("mydataset") = DsCategories1
// C#
sqlDataAdapter1.Update(dsCategories1);
Session["mydataset"] = dsCategories1;
使用对数据库的直接访问代替数据集
在演练中,您创建了一个数据集并将网格绑定到该数据集。若要更新数据库,首先更新数据集,然后使用数据适配器的 Update 方法将更改发送到数据库。
使用数据集便于执行更新,但其代价是一些内存和微小的性能系统开销。作为一种替代方法,您可以使用数据命令(OleDbCommand 类或 SqlCommand 类对象)直接执行 SQL 语句或存储过程。例如,您可以配置一个带有参数化 SQL Update 语句的数据命令来更新数据库中的 Categories 表。在获取网格中的更改之后,设置 Update 语句的参数然后执行它。
在解决方案资源管理器中,右击 Web 窗体页并选择“生成并浏览”。
当前项目将被编译,Web 窗体页将显示在设计器的浏览器窗格中。
单击网格中任何一行的“编辑”链接,然后使用文本框编辑该行。
单击“更新”。
网格重新显示,并带有您的更改。如果检查数据库,您将看到已适当写入更改。
下一步
在本演练中,您使用 Web 窗体页上的 DataGrid 控件不仅仅是查看数据,而是要编辑数据。为了清楚起见,本演练跳过了一些在成品应用程序中要考虑的细节。您要对本演练中所学的内容有所加强的一些方面包括:
增强 DataGrid 控件的功能
本演练没有利用 DataGrid 控件的某些更高级的功能。您可以增强的方面包括:
通过选择特定的要显示的列、更改列标题等配置网格中的个别列。有关详细信息,请参阅向 DataGrid Web 服务器控件添加绑定列和指定 DataGrid Web 服务器控件中网格项的格式
允许用户删除行。有关详细信息,请参阅允许用户删除 DataGrid Web 服务器控件中的项。除了指定“删除”按钮之外,您需要添加代码以从数据集中移除记录。有关详细信息,请参阅删除数据集中的记录。
使用分页。在本例中,您只显示几条记录。但是,经常要显示更多的记录,如果是这样,允许网格以一次一页的方式显示信息是非常必要的。有关详细信息,请参阅 DataGrid Web 服务器控件中的分页行为。
缓存数据集
在本演练中,页每次到服务器的往返行程都会使数据集重新实例化并从数据库重新填充数据集。这种策略虽然实现起来非常简单,但是却会导致到数据库服务器不必要的通信量。
一种替代方法是在填充数据集和每次更改数据集之后将数据集存储起来。于是您可以在每次往返行程发生后恢复数据集,而不用重新读取数据库信息。存储数据集有多种方法,其中包括存储在会话状态(在服务器上)或视图状态(在客户端上,页中)。有关要使用哪种策略的详细信息,请参阅状态管理建议。
例如,如果您要在会话状态中存储数据集,则可能要在 Page_Load 事件处理程序中包括以下代码:
' Visual Basic
If Not Page.IsPostBack Then
If Session("mydatset") Is Nothing Then
SqlDataAdapter1.Fill(dsCategories1)
Session("mydataset") = dsCategories1
Else
dsCategories1 = CType(Session("mydatset"), dsCategories)
End If
DataGrid1.DataBind()
End If
// C#
if (! Page.IsPostBack)
{
if (Session["mydatset"] == null)
{
sqlDataAdapter1.Fill(dsCategories1);
Session["mydataset"] = dsCategories1;
}
else
{
dsCategories1 = (dsCategories)Session["mydatset"];
}
DataGrid1.DataBind();
}
请注意,如果要在会话状态或应用程序状态中存储数据集,则当将其取回时需要将其强制转换为适当的数据集类型。
每次数据集更改时,一定要刷新会话状态中该数据集的副本。例如,您可能要在 UpdateCommand 事件处理程序中紧接在更新数据库之后添加下面一行:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
Session("mydataset") = DsCategories1
// C#
sqlDataAdapter1.Update(dsCategories1);
Session["mydataset"] = dsCategories1;
使用对数据库的直接访问代替数据集
在演练中,您创建了一个数据集并将网格绑定到该数据集。若要更新数据库,首先更新数据集,然后使用数据适配器的 Update 方法将更改发送到数据库。
使用数据集便于执行更新,但其代价是一些内存和微小的性能系统开销。作为一种替代方法,您可以使用数据命令(OleDbCommand 类或 SqlCommand 类对象)直接执行 SQL 语句或存储过程。例如,您可以配置一个带有参数化 SQL Update 语句的数据命令来更新数据库中的 Categories 表。在获取网格中的更改之后,设置 Update 语句的参数然后执行它。
#6
感谢上面三位答复,非常感谢!bwx()地回答好像是MSDN里边的原文吧,其实告诉我出处也就是地址就可以了,谢谢!
#1
下面的是update的例子,其他类似
private void dgdTeacher_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string[] strFields;
strFields=new string[6];
//得到关键字
strFields[0]=dgdTeacher.DataKeys[e.Item.ItemIndex].ToString();
//将datagrid行中各单元的值赋给数组
for(int i=1;i<5;i++)
{
strFields[i]=((TextBox)e.Item.Cells[i].Controls[0]).Text ;
}
//更新数据库,返回影响的行数
//1=更新成功,其他=更新失败
intAffectedRows=trainDataBus.Update_T_CRM_Teacher(strFields);
//退出更新模式,重新绑定数据
dgdTeacher.EditItemIndex=-1;
//重新绑定datagrid
GridBind();
}
private void dgdTeacher_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string[] strFields;
strFields=new string[6];
//得到关键字
strFields[0]=dgdTeacher.DataKeys[e.Item.ItemIndex].ToString();
//将datagrid行中各单元的值赋给数组
for(int i=1;i<5;i++)
{
strFields[i]=((TextBox)e.Item.Cells[i].Controls[0]).Text ;
}
//更新数据库,返回影响的行数
//1=更新成功,其他=更新失败
intAffectedRows=trainDataBus.Update_T_CRM_Teacher(strFields);
//退出更新模式,重新绑定数据
dgdTeacher.EditItemIndex=-1;
//重新绑定datagrid
GridBind();
}
#2
try something like
for (int i=0; i < DataGrid1.Items.Count;i++)
{
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[2].FindControl("dwjz");
string sValue = tb.Value;
HtmlInputText tb2 = (HtmlInputText)DataGrid1.Items[i].Cells[3].FindControl("ljjz");
string sValue2 = tb2.Value;
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[4].FindControl("wjshddwnfpsy");
string sValue3 = tb3.Value;
//...update the database
}
for (int i=0; i < DataGrid1.Items.Count;i++)
{
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[2].FindControl("dwjz");
string sValue = tb.Value;
HtmlInputText tb2 = (HtmlInputText)DataGrid1.Items[i].Cells[3].FindControl("ljjz");
string sValue2 = tb2.Value;
HtmlInputText tb = (HtmlInputText)DataGrid1.Items[i].Cells[4].FindControl("wjshddwnfpsy");
string sValue3 = tb3.Value;
//...update the database
}
#3
Visual Basic 和 Visual C# 概念
演练:使用 DataGrid Web 控件读取和写入数据请参见
演练:在 Web 窗体页中显示数据 | 演练:在 Web 窗体页中创建只读数据访问 | 演练:创建分布式应用程序 | 演练:在 Web 窗体中使用数据库更新查询更新数据 | 演练:验证 Web 窗体页中的用户输入
Web 窗体数据绑定的结构便于在页控件中显示数据。但是,数据绑定不是双向的,也就是说,数据绑定从数据源读取数据但不对其进行更新。更新比显示数据更复杂,因为大多数 Web 窗体页不需要将数据写回源,所以 Web 窗体数据绑定通过不包括更新代码将页大小和页处理保持在最精简的程度。
当然,有时候您要创建更新数据的 Web 窗体页。本演练阐释完成该目的的一种方式。它说明了如何使用 DataGrid 控件显示数据,允许用户对其进行编辑,然后将更改的数据发送回源。
当该页运行时,它看起来类似于下面这样:
若要完成本演练,您需要:
访问带有 Northwind SQL Server 示例数据库的服务器。
充足的权限,以便在 Web 服务器所在的计算机上创建 ASP.NET Web 应用程序项目。
演练被分成若干较小的部分:
创建 Web 窗体页。
添加必要的数据组件。
添加显示数据的 DataGrid 控件。
添加从数据库读取数据并将网格绑定到数据的代码。
配置 DataGrid 控件以允许用户编辑数据。
添加更新数据的代码。
创建项目和窗体
第一步是创建 Web 应用程序和 Web 窗体页。
创建项目和窗体
在“文件”菜单上指向“新建”,然后单击“项目”。
在“新建项目”对话框中,请执行以下操作:
在“项目类型”窗格中选择“Visual Basic 项目”或“Visual C# 项目”。
在“模板”窗格中选择“ASP.NET Web 应用程序”。
在“位置”框中,为您的应用程序输入完整的 URL(包含 http://、服务器名称和项目名称)。Web 服务器上必须安装 IIS 5 版(或更高版本)和 .NET 框架。如果计算机上已安装 IIS,可以为服务器指定 http://localhost。
当单击“确定”时,将在您指定的 Web 服务器的根处创建新的 Web 窗体项目。此外,名为 WebForm1.aspx 的新 Web 窗体页将显示在“设计”视图中 Web 窗体设计器上。
提示 如果在创建 Web 应用程序项目方面有困难,请参阅“Web 访问失败”对话框。
创建和配置数据集
在 Web 窗体页中,有多种访问数据的方法选择。一种方法是使用数据集,它是内存中的数据缓存。另外,您可以使用执行 SQL 语句或存储过程的数据命令直接访问数据库。一般情况下,使用数据集便于更新数据,这也正是您将在本演练中使用的方法。有关更多信息,请参阅 Web 数据访问策略建议。
您不直接将数据集添加到页。相反,您将执行下列一组步骤:
使用向导创建数据适配器。该适配器包含用于读取和写入数据库信息的 SQL 语句。该向导帮助您定义所需的 SQL 语句。如有必要,该向导还创建与数据库的连接。
生成数据集架构。在本过程中,您将让 Visual Studio 基于您正在访问的表和列创建一个新的数据集类。在生成数据集类时,您还将向窗体中添加该类的一个实例。
遵循本节中的所有过程很重要。否则,您的页将不具有在本演练的随后部分中将使用的数据集。
有关数据适配器的概述,请参阅数据适配器介绍。有关数据集的概述,请参阅数据集介绍。
配置数据连接和数据适配器
若要开始,请创建一个包含稍后用于填充数据集的 SQL 语句的数据适配器。作为此过程的一部分,定义连接以访问数据库。使用向导配置数据适配器,该向导使创建数据访问所需的 SQL 语句变得容易。
注意 向导完成后,您必须继续下一部分操作,以便生成数据集并完成该页的数据访问部分。
创建数据连接和数据适配器
从工具箱的“数据”选项卡中,将一个 SqlDataAdapter 对象拖到页上。
注意 如果您未使用 SQL Server,则应使用类型 OleDbDataAdapter 的适配器,它提供到任何与 OLE DB 兼容的数据源的访问。
“数据适配器配置向导”启动,它将帮助您创建连接和适配器。
在该向导中,执行下列操作:
在第二个窗格中,创建或选择一个指向 SQL Server Northwind 数据库的连接。有关访问数据库的信息,请与您的数据库管理员联系。
注意 您需要在所使用的 SQL Server 上具有适当的读/写权限。建议在创建连接时指定 Windows 集成安全性。或者,可以指定用户名和密码并将该信息与此连接保存在一起,但这样做会危及安全性。有关更多信息,请参阅数据库安全性。
在第三个窗格中,指定您要使用 SQL 语句访问数据库。
在第四个窗格中创建以下 SQL 语句:
SELECT CategoryID, CategoryName, Description
FROM Categories
有关如何生成 SQL 语句的帮助,请单击“查询生成器”启动“查询生成器”对话框。
注意 在本演练中,将使用类别表中的所有行来填充数据集。在成品应用程序中,通常通过创建只返回所需列和行的查询来优化数据访问。有关示例,请参阅演练:使用参数化查询在 Windows 窗体中显示数据。
单击“完成”。
向导创建一个连接(SqlConnection1 或 sqlConnection1),它包含有关如何访问数据库的信息。您还将具有包含一个查询的数据适配器(SqlDataAdapter1 或 sqlDataAdapter1),该查询定义所要访问数据库中的表和列。
向导完成后,您需要基于在该过程中创建的 SQL 查询生成数据集。有关详细信息,请参阅下一节。
创建数据集
建立连接到数据库的方法并指定所需的信息(通过数据适配器中的 SQL 命令)后,可以让 Visual Studio 创建数据集。Visual Studio 可以基于您为数据适配器指定的查询自动生成数据集。数据集是基于相应架构(.xsd 文件)的 DataSet 类的一个实例,该架构描述类的元素(表、列和约束)。有关数据集与架构之间关系的详细信息,请参阅 ADO.NET 数据访问介绍。
生成数据集
从“数据”菜单中选择“生成数据集”。
提示 如果“生成数据集”命令未启用,则单击该页;页必须具有焦点,该命令才会出现。
“生成数据集”对话框出现。
选择“新建”选项,将该数据集命名为 dsCategories。
在“选择要添加到数据集中的表”下面的列表中,确保选择了 Categories 表。
确保“将此数据集添加到设计器”已选中,然后单击“确定”。
Visual Studio 生成某类型化数据集类 (dsCategories) 和定义该数据集的架构。您将在解决方案资源管理器中看到新的架构 (dsCategories.xsd)。
提示 在解决方案资源管理器中,单击“显示所有文件”工具栏按钮以查看架构文件的相关 .vb 或 .cs 文件,该文件包含定义新数据集类的代码。
最后,Visual Studio 将新数据集类 (dsCategories1) 的实例添加到页上。
此刻,为执行从数据库获取信息并转移到数据集的操作所需的全部设置均已完成。
添加显示数据的 DataGrid 控件
在本演练中,您将添加单个控件(DataGrid 控件),该控件可以同时显示数据集中的所有记录并允许您添加编辑记录的功能。
数据网格必须绑定到数据集才能显示数据。
向窗体添加绑定 DataGrid 控件
如果尚未进行该操作,请单击当前窗口顶部的选项卡切换到 Web 窗体设计器。
从工具箱的“Web 窗体”选项卡中,将一个 DataGrid 控件拖到窗体上。
选择该控件,按 F4 键显示“属性”窗口,在窗口的底部,单击“属性生成器”。
“DataGrid 属性”对话框出现。
在“常规”选项卡中,完成以下设置:属性 设置 说明
数据源 dsCategories1 将网格绑定到数据集。
数据成员 Categories 指定网格应该显示数据集的类别表中的数据
数据键字段 CategoryID 指定类别记录的主键是 CategoryID 列。这将允许您稍后确定更新数据集中的哪个记录。
单击“确定”关闭“DataGrid 属性”对话框。
如果您要更改网格的外观,请设置“字体”、“背景色”和其他属性。
提示 一种简单的设置网格外观的方法是单击“属性”窗口底部的“自动套用格式”,然后选择预定义的外观。
填充数据集并在 DataGrid 控件中显示数据
尽管网格被绑定到所创建的数据集,但是,数据集本身不会被自动填写。相反,您必须自己调用数据适配器方法来填充数据集。有关填充数据集的详细信息,请参阅数据集介绍。
即使在数据集被填充后,DataGrid 控件仍不会自动显示数据。您必须将网格显式绑定到它的数据源。有关更多信息,请参阅 Web 窗体页中的数据绑定介绍。
填充数据集并在 DataGrid 控件中显示数据
双击当前页,在代码编辑器中显示该页的类文件。
在 Page_Load 事件处理程序中,调用数据适配器的 Fill 方法并向其传递要填充的数据集:
' Visual Basic
SqlDataAdapter1.Fill(DsCategories1)
//C#
sqlDataAdapter1.Fill(dsCategories1);
调用 DataGrid 控件的 DataBind 方法,将该控件绑定到数据集。但是,您不想在页每次进行往返行程时都重新绑定控件,因为如果这样做,将丢失用户已在网格中进行的更改。因此,您应该只在以下这些情况下绑定网格:
第一次调用页时。
数据集更改时。
现在,您要在第一次调用页时绑定网格,这可以通过测试页的 IsPostBack 属性完成。在调用了适配器的 Fill 方法之后将代码添加到 Page_Load 事件处理程序。完整的处理程序看起来将类似于下面这样:
' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
SqlDataAdapter1.Fill(DsCategories1)
If Not IsPostBack Then
DataGrid1.DataBind()
End If
End Sub
// C#
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
sqlDataAdapter1.Fill(dsCategories1);
if (!IsPostBack)
{
DataGrid1.DataBind();
}
}
添加编辑数据的功能
按照配置,DataGrid 控件将显示 Categories 表中的信息。但您还希望用户可以
演练:使用 DataGrid Web 控件读取和写入数据请参见
演练:在 Web 窗体页中显示数据 | 演练:在 Web 窗体页中创建只读数据访问 | 演练:创建分布式应用程序 | 演练:在 Web 窗体中使用数据库更新查询更新数据 | 演练:验证 Web 窗体页中的用户输入
Web 窗体数据绑定的结构便于在页控件中显示数据。但是,数据绑定不是双向的,也就是说,数据绑定从数据源读取数据但不对其进行更新。更新比显示数据更复杂,因为大多数 Web 窗体页不需要将数据写回源,所以 Web 窗体数据绑定通过不包括更新代码将页大小和页处理保持在最精简的程度。
当然,有时候您要创建更新数据的 Web 窗体页。本演练阐释完成该目的的一种方式。它说明了如何使用 DataGrid 控件显示数据,允许用户对其进行编辑,然后将更改的数据发送回源。
当该页运行时,它看起来类似于下面这样:
若要完成本演练,您需要:
访问带有 Northwind SQL Server 示例数据库的服务器。
充足的权限,以便在 Web 服务器所在的计算机上创建 ASP.NET Web 应用程序项目。
演练被分成若干较小的部分:
创建 Web 窗体页。
添加必要的数据组件。
添加显示数据的 DataGrid 控件。
添加从数据库读取数据并将网格绑定到数据的代码。
配置 DataGrid 控件以允许用户编辑数据。
添加更新数据的代码。
创建项目和窗体
第一步是创建 Web 应用程序和 Web 窗体页。
创建项目和窗体
在“文件”菜单上指向“新建”,然后单击“项目”。
在“新建项目”对话框中,请执行以下操作:
在“项目类型”窗格中选择“Visual Basic 项目”或“Visual C# 项目”。
在“模板”窗格中选择“ASP.NET Web 应用程序”。
在“位置”框中,为您的应用程序输入完整的 URL(包含 http://、服务器名称和项目名称)。Web 服务器上必须安装 IIS 5 版(或更高版本)和 .NET 框架。如果计算机上已安装 IIS,可以为服务器指定 http://localhost。
当单击“确定”时,将在您指定的 Web 服务器的根处创建新的 Web 窗体项目。此外,名为 WebForm1.aspx 的新 Web 窗体页将显示在“设计”视图中 Web 窗体设计器上。
提示 如果在创建 Web 应用程序项目方面有困难,请参阅“Web 访问失败”对话框。
创建和配置数据集
在 Web 窗体页中,有多种访问数据的方法选择。一种方法是使用数据集,它是内存中的数据缓存。另外,您可以使用执行 SQL 语句或存储过程的数据命令直接访问数据库。一般情况下,使用数据集便于更新数据,这也正是您将在本演练中使用的方法。有关更多信息,请参阅 Web 数据访问策略建议。
您不直接将数据集添加到页。相反,您将执行下列一组步骤:
使用向导创建数据适配器。该适配器包含用于读取和写入数据库信息的 SQL 语句。该向导帮助您定义所需的 SQL 语句。如有必要,该向导还创建与数据库的连接。
生成数据集架构。在本过程中,您将让 Visual Studio 基于您正在访问的表和列创建一个新的数据集类。在生成数据集类时,您还将向窗体中添加该类的一个实例。
遵循本节中的所有过程很重要。否则,您的页将不具有在本演练的随后部分中将使用的数据集。
有关数据适配器的概述,请参阅数据适配器介绍。有关数据集的概述,请参阅数据集介绍。
配置数据连接和数据适配器
若要开始,请创建一个包含稍后用于填充数据集的 SQL 语句的数据适配器。作为此过程的一部分,定义连接以访问数据库。使用向导配置数据适配器,该向导使创建数据访问所需的 SQL 语句变得容易。
注意 向导完成后,您必须继续下一部分操作,以便生成数据集并完成该页的数据访问部分。
创建数据连接和数据适配器
从工具箱的“数据”选项卡中,将一个 SqlDataAdapter 对象拖到页上。
注意 如果您未使用 SQL Server,则应使用类型 OleDbDataAdapter 的适配器,它提供到任何与 OLE DB 兼容的数据源的访问。
“数据适配器配置向导”启动,它将帮助您创建连接和适配器。
在该向导中,执行下列操作:
在第二个窗格中,创建或选择一个指向 SQL Server Northwind 数据库的连接。有关访问数据库的信息,请与您的数据库管理员联系。
注意 您需要在所使用的 SQL Server 上具有适当的读/写权限。建议在创建连接时指定 Windows 集成安全性。或者,可以指定用户名和密码并将该信息与此连接保存在一起,但这样做会危及安全性。有关更多信息,请参阅数据库安全性。
在第三个窗格中,指定您要使用 SQL 语句访问数据库。
在第四个窗格中创建以下 SQL 语句:
SELECT CategoryID, CategoryName, Description
FROM Categories
有关如何生成 SQL 语句的帮助,请单击“查询生成器”启动“查询生成器”对话框。
注意 在本演练中,将使用类别表中的所有行来填充数据集。在成品应用程序中,通常通过创建只返回所需列和行的查询来优化数据访问。有关示例,请参阅演练:使用参数化查询在 Windows 窗体中显示数据。
单击“完成”。
向导创建一个连接(SqlConnection1 或 sqlConnection1),它包含有关如何访问数据库的信息。您还将具有包含一个查询的数据适配器(SqlDataAdapter1 或 sqlDataAdapter1),该查询定义所要访问数据库中的表和列。
向导完成后,您需要基于在该过程中创建的 SQL 查询生成数据集。有关详细信息,请参阅下一节。
创建数据集
建立连接到数据库的方法并指定所需的信息(通过数据适配器中的 SQL 命令)后,可以让 Visual Studio 创建数据集。Visual Studio 可以基于您为数据适配器指定的查询自动生成数据集。数据集是基于相应架构(.xsd 文件)的 DataSet 类的一个实例,该架构描述类的元素(表、列和约束)。有关数据集与架构之间关系的详细信息,请参阅 ADO.NET 数据访问介绍。
生成数据集
从“数据”菜单中选择“生成数据集”。
提示 如果“生成数据集”命令未启用,则单击该页;页必须具有焦点,该命令才会出现。
“生成数据集”对话框出现。
选择“新建”选项,将该数据集命名为 dsCategories。
在“选择要添加到数据集中的表”下面的列表中,确保选择了 Categories 表。
确保“将此数据集添加到设计器”已选中,然后单击“确定”。
Visual Studio 生成某类型化数据集类 (dsCategories) 和定义该数据集的架构。您将在解决方案资源管理器中看到新的架构 (dsCategories.xsd)。
提示 在解决方案资源管理器中,单击“显示所有文件”工具栏按钮以查看架构文件的相关 .vb 或 .cs 文件,该文件包含定义新数据集类的代码。
最后,Visual Studio 将新数据集类 (dsCategories1) 的实例添加到页上。
此刻,为执行从数据库获取信息并转移到数据集的操作所需的全部设置均已完成。
添加显示数据的 DataGrid 控件
在本演练中,您将添加单个控件(DataGrid 控件),该控件可以同时显示数据集中的所有记录并允许您添加编辑记录的功能。
数据网格必须绑定到数据集才能显示数据。
向窗体添加绑定 DataGrid 控件
如果尚未进行该操作,请单击当前窗口顶部的选项卡切换到 Web 窗体设计器。
从工具箱的“Web 窗体”选项卡中,将一个 DataGrid 控件拖到窗体上。
选择该控件,按 F4 键显示“属性”窗口,在窗口的底部,单击“属性生成器”。
“DataGrid 属性”对话框出现。
在“常规”选项卡中,完成以下设置:属性 设置 说明
数据源 dsCategories1 将网格绑定到数据集。
数据成员 Categories 指定网格应该显示数据集的类别表中的数据
数据键字段 CategoryID 指定类别记录的主键是 CategoryID 列。这将允许您稍后确定更新数据集中的哪个记录。
单击“确定”关闭“DataGrid 属性”对话框。
如果您要更改网格的外观,请设置“字体”、“背景色”和其他属性。
提示 一种简单的设置网格外观的方法是单击“属性”窗口底部的“自动套用格式”,然后选择预定义的外观。
填充数据集并在 DataGrid 控件中显示数据
尽管网格被绑定到所创建的数据集,但是,数据集本身不会被自动填写。相反,您必须自己调用数据适配器方法来填充数据集。有关填充数据集的详细信息,请参阅数据集介绍。
即使在数据集被填充后,DataGrid 控件仍不会自动显示数据。您必须将网格显式绑定到它的数据源。有关更多信息,请参阅 Web 窗体页中的数据绑定介绍。
填充数据集并在 DataGrid 控件中显示数据
双击当前页,在代码编辑器中显示该页的类文件。
在 Page_Load 事件处理程序中,调用数据适配器的 Fill 方法并向其传递要填充的数据集:
' Visual Basic
SqlDataAdapter1.Fill(DsCategories1)
//C#
sqlDataAdapter1.Fill(dsCategories1);
调用 DataGrid 控件的 DataBind 方法,将该控件绑定到数据集。但是,您不想在页每次进行往返行程时都重新绑定控件,因为如果这样做,将丢失用户已在网格中进行的更改。因此,您应该只在以下这些情况下绑定网格:
第一次调用页时。
数据集更改时。
现在,您要在第一次调用页时绑定网格,这可以通过测试页的 IsPostBack 属性完成。在调用了适配器的 Fill 方法之后将代码添加到 Page_Load 事件处理程序。完整的处理程序看起来将类似于下面这样:
' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
SqlDataAdapter1.Fill(DsCategories1)
If Not IsPostBack Then
DataGrid1.DataBind()
End If
End Sub
// C#
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
sqlDataAdapter1.Fill(dsCategories1);
if (!IsPostBack)
{
DataGrid1.DataBind();
}
}
添加编辑数据的功能
按照配置,DataGrid 控件将显示 Categories 表中的信息。但您还希望用户可以
#4
创建 UpdateCommand 处理程序
(在 Visual Basic 中)如果尚未将其打开,则再次打开代码编辑器。
— 或 —
(在 Visual C# 中)在“设计”视图中,选择网格并按 F4 键打开“属性”窗口。
(在 Visual Basic 中)在代码编辑器上方的左侧下拉列表中选择“DataGrid1”。
— 或 —
(在 Visual C# 中)单击“属性”窗口顶部的“事件”按钮 ()。
(在 Visual Basic 中)在代码编辑器顶部右侧的下拉列表中选择“UpdateCommand”。
— 或 —
(在 Visual C# 中)双击网格中的“UpdateCommand”。
创建了一个 DataGrid1_UpdateCommand 事件处理程序。
从 DataGrid 控件进行更新的步骤
您将执行的操作的大纲如下:
确定 DataGrid 控件中哪一行(根据索引)已被更新。然后,从该网格行获取数据键,以便确定正在更新的行(根据 ID)。
从用户更新的网格行获取更改的值。
使用数据键值在数据集表中查找对应的行,然后将更改写入该行。此时,您已更新了数据集,但未更新数据库本身。
将更改从数据集发送到数据库。这执行将更改从数据集复制到数据库的 SQL 命令或存储过程。
刷新 DataGrid 控件的内容。
下面一节解释这些步骤中每一步的详细情况。如果愿意,您可以跳过这些解释,直接进入随后的代码。
从 DataGrid 控件进行更新
通过获取传入事件对象的行(Item 对象)的 ItemIndex 属性确定哪个 DataGrid 行已被更新。然后使用该索引值从网格的 DataKeys 集合中获取对应的值。
' Visual Basic
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString()
// C#
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
从 DataGrid 行中获取更改的值。若要完成该操作,请:
从传入事件对象的项的 Cells 集合中获取适当的单元格(从零开始的)。例如,网格中最左边一列为 Cells(0)。
对于每个单元格,获取其 Controls 集合,它包含显示在该单元格中的所有元素。
从该集合中获取第一个(并且只是第一个)控件,在本例中为 TextBox 控件。若要获取 TextBox,声明一个类型 TextBox 的局部变量,并将 Controls 集合中的对象分配给它。
获取 TextBox 控件的值(其 Text 属性)。
下面的示例显示如何执行这些步骤。
' Visual Basic
Dim categoryName, categoryDescription As String
Dim tb As TextBox
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
// C#
string categoryname;
string categoryDescription;
TextBox tb;
tb = (TextBox) e.Item.Cells[2].Controls[0];
categoryName = tb.Text;
tb = (TextBox) e.Item.Cells[3].Controls[0];
categoryDescription = tb.Text
在数据表中查找对应的行。类型化的 dsCategories 数据集包含一个特殊的 FindBy 方法(在本例中为 FindByCategoryID 方法),该方法通过行的主键定位行并返回一个对它的引用。创建类型化数据行的变量并调用该方法:
' Visual Basic
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
// C#
dsCategories.CategoriesRow r;
r = DsCategories1.Categories.FindByCategoryID(key);
通过更改您在第三步所在行中的值更新该行,如下面的示例所示:
' Visual Basic
r.CategoryName = categoryName
r.Description = categoryDescription
// C#
r.CategoryName = categoryName;
r.Description = categoryDescription;
通过调用数据适配器的 Update 方法将更改从数据集发送到数据库:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
DataGrid1.DataBind()
// C#
SqlDataAdapter1.Update(DsCategories1);
DataGrid1.DataBind();
将网格中的当前行切换出编辑模式。
' Visual Basic
DataGrid1.EditItemIndex = -1
// C#
DataGrid1.EditItemIndex = -1;
数据绑定 DataGrid 控件:
' Visual Basic
DataGrid1.DataBind()
// C#
DataGrid1.DataBind();
下面的代码显示完成的 UpdateCommand 事件处理程序是什么样的。复制该代码并将其粘贴到 Web 窗体页的类文件。
提示 一定要改写先前创建的主干事件处理程序,否则将有两个方法具有相同的名称和签名。
' Visual Basic
Private Sub DataGrid1_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.UpdateCommand
Dim categoryName, categoryDescription As String
' Gets the value of the key field of the row being updated
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString
' Gets get the value of the controls (textboxes) that the user
' updated. The DataGrid columns are exposed as the Cells collection.
' Each cell has a collection of controls. In this case, there is only one
' control in each cell -- a TextBox control. To get its value,
' you copy the TextBox to a local instance (which requires casting)
' and extract its Text property.
'
' The first column -- Cells(0) -- contains the Update and Cancel buttons.
Dim tb As TextBox
' Gets the value the TextBox control in the third column
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
' Gets the value the TextBox control in the fourth column
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
' Finds the row in the dataset table that matches the
' one the user updated in the grid. This example uses a
' special Find method defined for the typed dataset, which
' returns a reference to the row.
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
' Updates the dataset table.
r.CategoryName = categoryName
r.Description = categoryDescription
' Calls a SQL statement to update the database from the dataset
SqlDataAdapter1.Update(DsCategories1)
' Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1
' Refreshes the grid
DataGrid1.DataBind()
End Sub
// C#
private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string categoryName, categoryDescription;
// Gets the value of the key field of the row being updated
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
// Gets get the value of the controls (textboxes) that the user
// updated. The DataGrid columns are exposed as the Cells collection.
// Each cell has a collection of controls. In this case, there is only one
// control in each cell -- a TextBox control. To get its value,
// you copy the TextBox to a local instance (which requires casting)
// and extract its Text property.
//
// The first column -- Cells(0) -- contains the Update and Cancel buttons.
TextBox tb;
// Gets the value the TextBox control in the third column
tb = (TextBox)(e.Item.Cells[2].Controls[0]);
categoryName = tb.Text;
// Gets the value the TextBox control in the fourth column
tb = (TextBox)(e.Item.Cells[3].Controls[0]);
categoryDescription = tb.Text;
// Finds the row in the dataset table that matches the
// one the user updated in the grid. This example uses a
// special Find method defined for the typed dataset, which
// returns a reference to the row.
dsCategories.CategoriesRow r;
r = dsCategories1.Categories.FindByCategoryID(int.Parse(key));
// Updates the dataset table.
r.CategoryName = categoryName;
r.Description = categoryDescription;
// Calls a SQL statement to update the database from the dataset
sqlDataAdapter1.Update(dsCategories1);
// Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1;
// Refreshes the grid
DataGrid1.DataBind();
}
测试
现在您已完成所有操作。若要阐释网格如何工作并确保它正确更新数据,您应该对页进行测试。
(在 Visual Basic 中)如果尚未将其打开,则再次打开代码编辑器。
— 或 —
(在 Visual C# 中)在“设计”视图中,选择网格并按 F4 键打开“属性”窗口。
(在 Visual Basic 中)在代码编辑器上方的左侧下拉列表中选择“DataGrid1”。
— 或 —
(在 Visual C# 中)单击“属性”窗口顶部的“事件”按钮 ()。
(在 Visual Basic 中)在代码编辑器顶部右侧的下拉列表中选择“UpdateCommand”。
— 或 —
(在 Visual C# 中)双击网格中的“UpdateCommand”。
创建了一个 DataGrid1_UpdateCommand 事件处理程序。
从 DataGrid 控件进行更新的步骤
您将执行的操作的大纲如下:
确定 DataGrid 控件中哪一行(根据索引)已被更新。然后,从该网格行获取数据键,以便确定正在更新的行(根据 ID)。
从用户更新的网格行获取更改的值。
使用数据键值在数据集表中查找对应的行,然后将更改写入该行。此时,您已更新了数据集,但未更新数据库本身。
将更改从数据集发送到数据库。这执行将更改从数据集复制到数据库的 SQL 命令或存储过程。
刷新 DataGrid 控件的内容。
下面一节解释这些步骤中每一步的详细情况。如果愿意,您可以跳过这些解释,直接进入随后的代码。
从 DataGrid 控件进行更新
通过获取传入事件对象的行(Item 对象)的 ItemIndex 属性确定哪个 DataGrid 行已被更新。然后使用该索引值从网格的 DataKeys 集合中获取对应的值。
' Visual Basic
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString()
// C#
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
从 DataGrid 行中获取更改的值。若要完成该操作,请:
从传入事件对象的项的 Cells 集合中获取适当的单元格(从零开始的)。例如,网格中最左边一列为 Cells(0)。
对于每个单元格,获取其 Controls 集合,它包含显示在该单元格中的所有元素。
从该集合中获取第一个(并且只是第一个)控件,在本例中为 TextBox 控件。若要获取 TextBox,声明一个类型 TextBox 的局部变量,并将 Controls 集合中的对象分配给它。
获取 TextBox 控件的值(其 Text 属性)。
下面的示例显示如何执行这些步骤。
' Visual Basic
Dim categoryName, categoryDescription As String
Dim tb As TextBox
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
// C#
string categoryname;
string categoryDescription;
TextBox tb;
tb = (TextBox) e.Item.Cells[2].Controls[0];
categoryName = tb.Text;
tb = (TextBox) e.Item.Cells[3].Controls[0];
categoryDescription = tb.Text
在数据表中查找对应的行。类型化的 dsCategories 数据集包含一个特殊的 FindBy 方法(在本例中为 FindByCategoryID 方法),该方法通过行的主键定位行并返回一个对它的引用。创建类型化数据行的变量并调用该方法:
' Visual Basic
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
// C#
dsCategories.CategoriesRow r;
r = DsCategories1.Categories.FindByCategoryID(key);
通过更改您在第三步所在行中的值更新该行,如下面的示例所示:
' Visual Basic
r.CategoryName = categoryName
r.Description = categoryDescription
// C#
r.CategoryName = categoryName;
r.Description = categoryDescription;
通过调用数据适配器的 Update 方法将更改从数据集发送到数据库:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
DataGrid1.DataBind()
// C#
SqlDataAdapter1.Update(DsCategories1);
DataGrid1.DataBind();
将网格中的当前行切换出编辑模式。
' Visual Basic
DataGrid1.EditItemIndex = -1
// C#
DataGrid1.EditItemIndex = -1;
数据绑定 DataGrid 控件:
' Visual Basic
DataGrid1.DataBind()
// C#
DataGrid1.DataBind();
下面的代码显示完成的 UpdateCommand 事件处理程序是什么样的。复制该代码并将其粘贴到 Web 窗体页的类文件。
提示 一定要改写先前创建的主干事件处理程序,否则将有两个方法具有相同的名称和签名。
' Visual Basic
Private Sub DataGrid1_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.UpdateCommand
Dim categoryName, categoryDescription As String
' Gets the value of the key field of the row being updated
Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString
' Gets get the value of the controls (textboxes) that the user
' updated. The DataGrid columns are exposed as the Cells collection.
' Each cell has a collection of controls. In this case, there is only one
' control in each cell -- a TextBox control. To get its value,
' you copy the TextBox to a local instance (which requires casting)
' and extract its Text property.
'
' The first column -- Cells(0) -- contains the Update and Cancel buttons.
Dim tb As TextBox
' Gets the value the TextBox control in the third column
tb = CType(e.Item.Cells(2).Controls(0), TextBox)
categoryName = tb.Text
' Gets the value the TextBox control in the fourth column
tb = CType(e.Item.Cells(3).Controls(0), TextBox)
categoryDescription = tb.Text
' Finds the row in the dataset table that matches the
' one the user updated in the grid. This example uses a
' special Find method defined for the typed dataset, which
' returns a reference to the row.
Dim r As dsCategories.CategoriesRow
r = DsCategories1.Categories.FindByCategoryID(key)
' Updates the dataset table.
r.CategoryName = categoryName
r.Description = categoryDescription
' Calls a SQL statement to update the database from the dataset
SqlDataAdapter1.Update(DsCategories1)
' Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1
' Refreshes the grid
DataGrid1.DataBind()
End Sub
// C#
private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
string categoryName, categoryDescription;
// Gets the value of the key field of the row being updated
string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
// Gets get the value of the controls (textboxes) that the user
// updated. The DataGrid columns are exposed as the Cells collection.
// Each cell has a collection of controls. In this case, there is only one
// control in each cell -- a TextBox control. To get its value,
// you copy the TextBox to a local instance (which requires casting)
// and extract its Text property.
//
// The first column -- Cells(0) -- contains the Update and Cancel buttons.
TextBox tb;
// Gets the value the TextBox control in the third column
tb = (TextBox)(e.Item.Cells[2].Controls[0]);
categoryName = tb.Text;
// Gets the value the TextBox control in the fourth column
tb = (TextBox)(e.Item.Cells[3].Controls[0]);
categoryDescription = tb.Text;
// Finds the row in the dataset table that matches the
// one the user updated in the grid. This example uses a
// special Find method defined for the typed dataset, which
// returns a reference to the row.
dsCategories.CategoriesRow r;
r = dsCategories1.Categories.FindByCategoryID(int.Parse(key));
// Updates the dataset table.
r.CategoryName = categoryName;
r.Description = categoryDescription;
// Calls a SQL statement to update the database from the dataset
sqlDataAdapter1.Update(dsCategories1);
// Takes the DataGrid row out of editing mode
DataGrid1.EditItemIndex = -1;
// Refreshes the grid
DataGrid1.DataBind();
}
测试
现在您已完成所有操作。若要阐释网格如何工作并确保它正确更新数据,您应该对页进行测试。
#5
对页进行测试
在解决方案资源管理器中,右击 Web 窗体页并选择“生成并浏览”。
当前项目将被编译,Web 窗体页将显示在设计器的浏览器窗格中。
单击网格中任何一行的“编辑”链接,然后使用文本框编辑该行。
单击“更新”。
网格重新显示,并带有您的更改。如果检查数据库,您将看到已适当写入更改。
下一步
在本演练中,您使用 Web 窗体页上的 DataGrid 控件不仅仅是查看数据,而是要编辑数据。为了清楚起见,本演练跳过了一些在成品应用程序中要考虑的细节。您要对本演练中所学的内容有所加强的一些方面包括:
增强 DataGrid 控件的功能
本演练没有利用 DataGrid 控件的某些更高级的功能。您可以增强的方面包括:
通过选择特定的要显示的列、更改列标题等配置网格中的个别列。有关详细信息,请参阅向 DataGrid Web 服务器控件添加绑定列和指定 DataGrid Web 服务器控件中网格项的格式
允许用户删除行。有关详细信息,请参阅允许用户删除 DataGrid Web 服务器控件中的项。除了指定“删除”按钮之外,您需要添加代码以从数据集中移除记录。有关详细信息,请参阅删除数据集中的记录。
使用分页。在本例中,您只显示几条记录。但是,经常要显示更多的记录,如果是这样,允许网格以一次一页的方式显示信息是非常必要的。有关详细信息,请参阅 DataGrid Web 服务器控件中的分页行为。
缓存数据集
在本演练中,页每次到服务器的往返行程都会使数据集重新实例化并从数据库重新填充数据集。这种策略虽然实现起来非常简单,但是却会导致到数据库服务器不必要的通信量。
一种替代方法是在填充数据集和每次更改数据集之后将数据集存储起来。于是您可以在每次往返行程发生后恢复数据集,而不用重新读取数据库信息。存储数据集有多种方法,其中包括存储在会话状态(在服务器上)或视图状态(在客户端上,页中)。有关要使用哪种策略的详细信息,请参阅状态管理建议。
例如,如果您要在会话状态中存储数据集,则可能要在 Page_Load 事件处理程序中包括以下代码:
' Visual Basic
If Not Page.IsPostBack Then
If Session("mydatset") Is Nothing Then
SqlDataAdapter1.Fill(dsCategories1)
Session("mydataset") = dsCategories1
Else
dsCategories1 = CType(Session("mydatset"), dsCategories)
End If
DataGrid1.DataBind()
End If
// C#
if (! Page.IsPostBack)
{
if (Session["mydatset"] == null)
{
sqlDataAdapter1.Fill(dsCategories1);
Session["mydataset"] = dsCategories1;
}
else
{
dsCategories1 = (dsCategories)Session["mydatset"];
}
DataGrid1.DataBind();
}
请注意,如果要在会话状态或应用程序状态中存储数据集,则当将其取回时需要将其强制转换为适当的数据集类型。
每次数据集更改时,一定要刷新会话状态中该数据集的副本。例如,您可能要在 UpdateCommand 事件处理程序中紧接在更新数据库之后添加下面一行:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
Session("mydataset") = DsCategories1
// C#
sqlDataAdapter1.Update(dsCategories1);
Session["mydataset"] = dsCategories1;
使用对数据库的直接访问代替数据集
在演练中,您创建了一个数据集并将网格绑定到该数据集。若要更新数据库,首先更新数据集,然后使用数据适配器的 Update 方法将更改发送到数据库。
使用数据集便于执行更新,但其代价是一些内存和微小的性能系统开销。作为一种替代方法,您可以使用数据命令(OleDbCommand 类或 SqlCommand 类对象)直接执行 SQL 语句或存储过程。例如,您可以配置一个带有参数化 SQL Update 语句的数据命令来更新数据库中的 Categories 表。在获取网格中的更改之后,设置 Update 语句的参数然后执行它。
在解决方案资源管理器中,右击 Web 窗体页并选择“生成并浏览”。
当前项目将被编译,Web 窗体页将显示在设计器的浏览器窗格中。
单击网格中任何一行的“编辑”链接,然后使用文本框编辑该行。
单击“更新”。
网格重新显示,并带有您的更改。如果检查数据库,您将看到已适当写入更改。
下一步
在本演练中,您使用 Web 窗体页上的 DataGrid 控件不仅仅是查看数据,而是要编辑数据。为了清楚起见,本演练跳过了一些在成品应用程序中要考虑的细节。您要对本演练中所学的内容有所加强的一些方面包括:
增强 DataGrid 控件的功能
本演练没有利用 DataGrid 控件的某些更高级的功能。您可以增强的方面包括:
通过选择特定的要显示的列、更改列标题等配置网格中的个别列。有关详细信息,请参阅向 DataGrid Web 服务器控件添加绑定列和指定 DataGrid Web 服务器控件中网格项的格式
允许用户删除行。有关详细信息,请参阅允许用户删除 DataGrid Web 服务器控件中的项。除了指定“删除”按钮之外,您需要添加代码以从数据集中移除记录。有关详细信息,请参阅删除数据集中的记录。
使用分页。在本例中,您只显示几条记录。但是,经常要显示更多的记录,如果是这样,允许网格以一次一页的方式显示信息是非常必要的。有关详细信息,请参阅 DataGrid Web 服务器控件中的分页行为。
缓存数据集
在本演练中,页每次到服务器的往返行程都会使数据集重新实例化并从数据库重新填充数据集。这种策略虽然实现起来非常简单,但是却会导致到数据库服务器不必要的通信量。
一种替代方法是在填充数据集和每次更改数据集之后将数据集存储起来。于是您可以在每次往返行程发生后恢复数据集,而不用重新读取数据库信息。存储数据集有多种方法,其中包括存储在会话状态(在服务器上)或视图状态(在客户端上,页中)。有关要使用哪种策略的详细信息,请参阅状态管理建议。
例如,如果您要在会话状态中存储数据集,则可能要在 Page_Load 事件处理程序中包括以下代码:
' Visual Basic
If Not Page.IsPostBack Then
If Session("mydatset") Is Nothing Then
SqlDataAdapter1.Fill(dsCategories1)
Session("mydataset") = dsCategories1
Else
dsCategories1 = CType(Session("mydatset"), dsCategories)
End If
DataGrid1.DataBind()
End If
// C#
if (! Page.IsPostBack)
{
if (Session["mydatset"] == null)
{
sqlDataAdapter1.Fill(dsCategories1);
Session["mydataset"] = dsCategories1;
}
else
{
dsCategories1 = (dsCategories)Session["mydatset"];
}
DataGrid1.DataBind();
}
请注意,如果要在会话状态或应用程序状态中存储数据集,则当将其取回时需要将其强制转换为适当的数据集类型。
每次数据集更改时,一定要刷新会话状态中该数据集的副本。例如,您可能要在 UpdateCommand 事件处理程序中紧接在更新数据库之后添加下面一行:
' Visual Basic
SqlDataAdapter1.Update(DsCategories1)
Session("mydataset") = DsCategories1
// C#
sqlDataAdapter1.Update(dsCategories1);
Session["mydataset"] = dsCategories1;
使用对数据库的直接访问代替数据集
在演练中,您创建了一个数据集并将网格绑定到该数据集。若要更新数据库,首先更新数据集,然后使用数据适配器的 Update 方法将更改发送到数据库。
使用数据集便于执行更新,但其代价是一些内存和微小的性能系统开销。作为一种替代方法,您可以使用数据命令(OleDbCommand 类或 SqlCommand 类对象)直接执行 SQL 语句或存储过程。例如,您可以配置一个带有参数化 SQL Update 语句的数据命令来更新数据库中的 Categories 表。在获取网格中的更改之后,设置 Update 语句的参数然后执行它。
#6
感谢上面三位答复,非常感谢!bwx()地回答好像是MSDN里边的原文吧,其实告诉我出处也就是地址就可以了,谢谢!