感受DataGrid给数据操作带来的便利 - asp.net 教程-
时间:2010-08-27 来源:星空3
作为一个刚刚接触asp.net的人来说,DataGrid能够为我们提供那些便利,一直是我想要早点知道的。这两天我恰好自己动手在修改以前的一个asp应用,所以,我学习了一下DataGrid,体会了一下,确实为我们带来了很多的便利,总结了一下,写出来给像我这样的初学者。
第一部分:用DataGrid显示数据表中的所有的数据
我们使用DataGrid的一个目的就是要用它来显示数据。我们首先要在页面上放上一个DataGrid,比如DataGrid1,接下来,我们要在页面的定义一个全局的数据库链接,你可以从vs.net2003的工具箱里创建一个“SqlConnection”,比如“myConn”,系统会再生成WebForm的时候,初始化它,你也可以在页面的page_load事件中初始化它:
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
this.myConn.ConnectionString = "workstation id=test;packet size=4096;integrated security=SSPI;data source=A" +"PPSERVER;persist security info=False;initial catalog=oa";
}
//为了方便,我创建了一个函数来填充数据到DataGrid
BindGrid();
}
创建一个函数BindGrid();
Public void BindGrid()
{
//创建一个适配器
SqlDataAdapter myAdp=new SqlDataAdapter("select * from mytable",myConn);
//创建一个数据集
DataSet ds=new DataSet();
//然后,通过适配器将数据库中的数据填充到数据集中
myAdp.Fill(ds,"myTable");//myTable是数据库表的名字
//将数据集作为DataGrid的数据源
DataGrid1.DataSource=ds.Tables["mytable"].DefaultView;
//绑定数据,数据就显示出来了
DataGrid1.DataBind();
}
OK,显示出来了!
编程量真的比原来asp要少多了,还快很多呢。
第二节:定制DataGrid的外观
上一篇文章中,我初步感受到了DataGrid给我带来的便利,但是,如果是我们自己编写程序画的表格的话,我们能够很灵活的控制表格的表现形式,所以,DataGrid能不能定制它的表现形式。答案,我知道肯定是可以的,关键是它是否比我自己用代码“画”要来得快。
根据以往的经验,我知道,从DataGrid的属性中就可以完成这些操作。
1、选择要显示的列:
在默认的情况下,我们在DataGrid中显示的列就是我们在执行Sql查询语句的时候查询出来的列,什么意思呢?如果我们用Select * from myTable,那么,将会显示所有的列,如果,我们用Select field1,field2 from mytable那么就只显示两个列。所以,在Datagrid中要选择你要显示的列,最简单的方法不是修改属性来完成,而是通过修改Sql查询语句来完成。
还有一个小问题,就是,我们在设计数据库的时候,字段的名称往往是英文的,但是,我们有想在DataGrid中使用中文,我们就需要在select语句中给每个字段取一个中文的别名,比如:Select Name As 姓名,cardid as 工号 from mytable。
有时候,我们不方便用这种方式来选择我们要显示的列,那么,我们就使用属性生成器来设置好了。
在设计视图中,选中DataGrid,然后 “属性窗口”的最下方就会有“属性生成器”的链接,点击这个链接(或者找到columns属性),会弹出一个对话框,我们就可以通过这个对话框来设置要选择的列了:
首先,我们去掉“在运行时自动创建列”前面的钩,这样,系统不再自动创建列,而只显示你绑定的列。
单击左侧的“列”,在右边就出现了“绑定列”“按钮列”等等,这里我们要选择“绑定列”。加入一个绑定列,然后,分别填写“页眉文本”等项目。页眉文本指的是页标题,“数据字段”填写你要显示的字段名称。然后,你要绑定几个字段,就选择几个绑定列。
2、修改DataGrid的样式
默认情况下的DataGrid画出来的表格很难看,所以,我需要定制它的样式。选中DataGrid,属性窗口中的最下方就会出现一个“自动套用格式”的链接,单击这个链接,就会弹出一个让你选择格式的对话框,选择你中意的格式。
我不知道你会怎么认为,反正,我觉得这里面有两种格式很合我的胃口,并且,也符合公司的设计规范,所以,我往往会使用这些格式。如果你还不满意,那么你就需要自己定制了。自己定制也很简单,就是,你去修改“样式”类的属性值就可以了。另外,你还可以通过属性生成器来完成样式属性的修改。比如,你不想让你的表格回行,那么,你就到属性生成器中,选择“格式”,然后,在右边选择“项”,把各个分项中的“单元格内文本换行”前面的钩去掉就ok了。
第三节:快速分页
在第二节中,我体会到了DataGrid在定制外观上的快捷和方便,这一节,我又学会了快速的将数据分页。
我们在查询数据库的时候,往往不会用一个页面来显示所有的数据,而是对数据进行分页显示。记得在asp中,我们编写一个分页的页面非常麻烦,当我,学会了用DataGrid来Render数据的时候,我兴奋不已,因为,它做数据分页原来这么简单。
还是打开属性生成器(或者修改“分页”类的属性),这个时候你肯定知道要去选择左侧的“分页”分支。在右边,选择“允许分页”,然后,设置每一页显示的条数,页导航条的位置、名称等。你是不是认为这样就可以了,起初我也这么认为的,以为这样就可以了,但是,当我运行这个程序的时候,发现单击导航条后并没有什么反应。因为,我们还要编写几句代码来完成这个操作。
我们选中DataGrid,然后在属性窗口的顶端的标签里选择事件标签(因为我们要创建翻页的事件嘛),找到“PageIndexChanged”事件,编写下面的代码:
private void DataGrid1_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
DataGrid1.CurrentPageIndex=e.NewPageIndex;
BindGrid();
}
呵呵,好“长”的代码呀!
解释一下:
DataGrid1它有一个属性叫CurrentPageInde来指定现在要显示第几页。而“PageIndexChanged”这个事件的“e”参数呢,恰好可以告诉DagtaGrid1应该显示哪一页。
BindGrid()就是我在第一节中那个用来绑定数据的函数了,不用我再写一遍了吧,查查第一节的文章好了。
就这么简单,不信,你试试。
第四节:编辑数据
不知道各位在asp程序中是怎样来修改数据库记录的,反正我的做法是做一个列表,将所有的记录列出来,然后,在关键字段加上超级链接,然后在用户点击超链接后,将页面转发到一个新的编辑页面上。在那个时候,我多么想想编辑Excel表格那样就在自己的列表里修改我想修改的字段。然后,DataGrid就为我提供了这样的功能。在DataGrid中,可以通过属性生成器在数据列表的前面增加一个“编辑”操作列,即在每一条记录的前面(每一行)都会增加一个“编辑”的超链接,单击这个超链接,这一行就会变成可以编辑的,每个字段都会变成一个文本框,这时,操作列就会变成“更新”和“取消”。这是,我们只需要修改我们需要修改的数据,然后,单击更新保存程序就行了(更新事件当然要写代码了)。
主要的步骤如下:
首先,启动属性生成器(不知道怎么启动,就看看我前面的文章),然后,选择左侧的“列”,在右边的“可用列”中,我们展开“按钮列”,然后,选择“编辑、更新、取消”,单击“〉”按钮将其加入“选定列”,这样,我们的DataGrid就会自动增加一列。
然后,回到属性窗口,增加三个事件,一个是单击“编辑”链接后产生的事件EditCommand,一个是更新数据的事件,UpdateCommand,一个是取消事件,CancleCommand。
在EditCommand中加入代码,告诉程序,选择的这一行需要编辑:
private void DataGrid1_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex=(int)e.Item.ItemIndex;//告诉DataGrid第几行要编辑
BindGrid();//我在第一节写的函数,这里不重复了
}
完成了这段代码,你就会发现,它会乖乖地按照你的指令将你选择的这一行变成可编辑的。但是,当你单击“更新”、“取消”链接的时候,它并不理睬你。这是因为,我们还没有为这两个事件编写代码,我们先来写“取消”的代码:
private void DataGrid1_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex=-1;//将-1传递给DataGrid的EditItemIndex属性,它就会回到只读状态
BindGrid();
}
简单的事情,做完了,我们在来做最负责的事情——更新数据:
//由于例子程序丢了,这里重新作了一个
private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
String updateCmd = "UPDATE Authors SET au_id = @Id, au_lname = @LName, au_fname = @FName, phone = @Phone, "
+ "address = @Address, city = @City, state = @State, zip = @Zip, contract = @Contract where au_id = @Id";
//应该了解ADO.net中的参数化编程吧
SqlCommand myCommand = new SqlCommand(updateCmd, myConnection);
myCommand.Parameters.Add(new SqlParameter("@Id", SqlDbType.NVarChar, 11));
myCommand.Parameters.Add(new SqlParameter("@LName", SqlDbType.NVarChar, 40));
myCommand.Parameters.Add(new SqlParameter("@FName", SqlDbType.NVarChar, 20));
myCommand.Parameters.Add(new SqlParameter("@Phone", SqlDbType.NChar, 12));
myCommand.Parameters.Add(new SqlParameter("@Address", SqlDbType.NVarChar, 40));
myCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.NVarChar, 20));
myCommand.Parameters.Add(new SqlParameter("@State", SqlDbType.NChar, 2));
myCommand.Parameters.Add(new SqlParameter("@Zip", SqlDbType.NChar, 5));
myCommand.Parameters.Add(new SqlParameter("@Contract", SqlDbType.NVarChar,1));
myCommand.Parameters["@Id"].Value = MyDataGrid.DataKeys[(int)e.Item.ItemIndex];
//这个地方忘了告诉大家,我们必须在DataGrid中设置DataKeyField属性,MyDataGrid.DataKeys[(int)e.Item.ItemIndex]才能取得想要的关键字
int numCols = e.Item.Cells.Count;
for (int i=2; i<numCols-1; i++) //skip first, second and last column
{
String colvalue =((System.Web.UI.WebControls.TextBox)e.Item.Cells[i].Controls[0]).Text;
//中间你最好加上输入验证,然后再执行下列语句赋值给参数。
myCommand.Parameters[cols[i-1]].Value = colvalue;
}
myCommand.Connection.Open();
try
{
//更新数据
myCommand.ExecuteNonQuery();
//恢复只读状态
MyDataGrid.EditItemIndex = -1;
}
catch (SqlException exc)
{
//出错处理
}
myCommand.Connection.Close();
BindGrid();//重新绑定数据,用的还是我原来写的那样的函数
}
好了,我们的工作做完了,这段代码看上去很长,其实,是因为它用了比较多的字段,所以要用比较多的参数,我把关键部分用红字标出来了。其实还是很简单的。
第五节:删除条目
相对第四节的更新数据来说要删除条目就简单多了。关键步骤如下:
增加一个删除的按钮列,怎么增加参照第四节讲的。
设置DataGrid的DataKeyField属性,必须设置为数据库的关键字。
添加DeleteCommand事件,编写代码:
public void MyDataGrid_Delete(Object sender, DataGridCommandEventArgs e)
{
String deleteCmd = "DELETE from Employee where emp_id = @Id";
SqlCommand myCommand = new SqlCommand(deleteCmd, myConnection);
myCommand.Parameters.Add(new SqlParameter("@Id", SqlDbType.NVarChar, 11));
myCommand.Parameters["@Id"].Value = MyDataGrid.DataKeys[(int)e.Item.ItemIndex];
myCommand.Connection.Open();
try
{
myCommand.ExecuteNonQuery();
}
catch (SqlException)
{
}
myCommand.Connection.Close();
BindGrid();
}
第六节:按列排序
我们在使用数据时,常常要对数据进行排序,那么在这方面DataGrid为我们提供了什么呢?是不是像其他功能那样很轻松就可以实现呢?我刚刚体验了一下,答案是:真的很简单。
首先,我要设置DataGrid的属性,允许它排序,属性名称是:AllowSorting,默认是False,我们设置为True,这个时候,如果你编译运行的话,你就会发现每一列的标题都加上了超链接。不过,这个时候,你点击这些标题并没有什么反应,这是因为,你还没有为这些事件编写代码。我们到属性窗口创建事件OnSortCommand()——单击列标题排序时候发生的事件。
你可以直接在这个函数中编写用于DataGrid重新绑定数据的代码,我呢,这里还是想改造一下我前面一直在用的函数BindGrid()。
首先,我要给它增加一个参数,用于告诉程序,应该按照哪个列来排序,我的函数编程了BindGrid(string sortField)
然后呢,我要增加一个DataView来对数据进行排序。我们来看详细的代码,注意,改动的部分,我用红色标出来:
public void BindGrid(string strSortField)
{
string selectCmd="select 流水号 as id,姓名 as name,公司 as Company from sheet1$";
SqlDataAdapter mycomm=new SqlDataAdapter(selectCmd,cn);
DataSet ds=new DataSet();
mycomm.Fill(ds,"sheet1$");
DataView Source=ds.Tables["Sheet1$"].DefaultView;
Source.Sort=strSortField;
DataGrid1.DataSource=Source;///ds.Tables["sheet1$"].DefaultView;//原来是直接把Ds的数据给DataSource
DataGrid1.DataBind();
}
我们在OnSrotCommand事件中应用这个函数:
private void DataGrid1_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
//参数e用于传递列名
BindGrid(e.SortExpression);
}
如果我们要按倒序或者按顺序排序,我们可以加上“ ASC” 或“ DESC”,如:
private void DataGrid1_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
//参数e用于传递列名
BindGrid(e.SortExpression+" DESC");
}
我们经常会有这样的需求,单击一下列标题,顺序排序,再单击一下列标题,逆序排序,下列代码来完成这样的事情:
private void DataGrid1_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
DataGrid1.CurrentPageIndex=0;
if(Label1.Text=="1")//在web程序中,我喜欢用控件来保存全局变量
{
BindGrid(e.SortExpression+" DESC");
Label1.Text="0";
}
else
{
BindGrid(e.SortExpression+" ASC");
Label1.Text="1";
}
}