文本版|topic 高级搜索
   名人堂 帮助 论坛制度 意见反馈 | 首页 博客 周新贴 专题 求职 读书
RSS 底部
 
社区导航: 专家门诊   网络技术   操作系统   数据库   程序设计   系统应用   考试认证   CIO及信息化   站长交流   综合交流   下载基地  51CTO产品服务 设为首页 | 收藏本站
51CTO技术论坛» .Net » 再问在asp.net中使用datagrid的问题       [ 打印]  [ 订阅]  [ 收藏]  [ 推荐给朋友]   [ 本帖文本页]

论坛跳转:
     
标题: [求助] 再问在asp.net中使用datagrid的问题  ( 查看:653  回复:4 )   
 该主题悬赏的10无忧币已被全部领完 
 
clever101
新新人类  点击可查看详细



十二生肖之狗   双鱼座   行业勋章   技术勋章   诚信兄弟  
帖子 52
精华 0
无忧币 26
积分 143
阅读权限 20
注册日期 2007-7-22
最后登录 2007-10-15 离线

[查看资料]  [发短消息]  [Blog
       
发表于:2007-9-10 09:04   标题:再问在asp.net中使用datagrid的问题
上一帖 |
在asp.net中使用datagrid,常规的方法是使用datagrid邦定一个datasource,但这样做的话我不知道初始化datagrid,就是不显示任何记录,只显示标题列。现在我使用的是一个笨办法:就是构造一个查不到任何记录的sql语句,然后查询,再绑定datasource。但是显然这样的查询是多余的。最好的办法是什么呢?
    请教了一位大虾,他说可以自己构建一个空数据的DataTable(带字段的),再绑定。具体代码如下:
DataTable dt=new DataTable();
dt.Columns.Add("a");
dt.Columns.Add("b");
dt.Columns.Add("c");
BindNoRecords(DataGrid1,dt);

public void BindNoRecords(DataGrid gridView, DataTable dt)//GridView無數據顯示表頭
    {
        if (dt.Rows.Count == 0)
        {
            dt.Rows.Add(dt.NewRow());
            gridView.DataSource = dt;
            gridView.DataBind();
            int columnCount = gridView.Items[0].Cells.Count;
            gridView.Items[0].Cells.Clear();
            gridView.Items[0].Cells.Add(new TableCell());
            gridView.Items[0].Cells[0].ColumnSpan = columnCount;
            gridView.Items[0].Cells[0].Text = "No data found";
            gridView.ItemStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
        }
    }

    但是现在还有一个问题:就是因为这个datagrid的标题列是动态绑定的,就是怎样把查询到的记录绑定到这个datagrid。就是之前我使用静态列的时候这样做的:
TOracle oDB = new TOracleDB(strSql); // strSql为查询sql语句
DataGrid ResultList.DataSource = oDB.DataSource;
ResultList.DataBind;
   不知现在是否可以这样做:
TOracle oDB = new TOracleDB(strSql);
DataTable dt = oDB.DataSource.Table;
DataGrid ResultList.DataSource = dt;
ResultList.DataBind;
    我又想这样做会不会把那些标题列去掉。望大虾们指教。



网络虽虚拟,技术无边界,来看看大家“真面目”!
2007-9-10 09:041楼
[ 顶部 ]
 
redking
副版主  点击可查看详细


十二生肖之狗   双鱼座   行业勋章   技术勋章   诚信兄弟   中秋活动勋章  
帖子 2657
精华 0
无忧币 34792
积分 4345
阅读权限 140
来自 (保密)
注册日期 2006-7-11
最后登录 2008-9-5 离线

[查看资料]  [发短消息]  [Blog
[个人主页]    QQ       
发表于:2007-9-11 10:50 
DataGrid/DataList在ASP.NET非常重要,凡显示Table类型的数据,大多会使用这两个控件。
一、方法

1、DataBind

很简单、最常用的方法。绑定数据用。需要注意的只有一点:执行了这个方法后,DataGrid(由于DataGrid和DataList极为相似,所以下面的介绍虽然是针对DataGrid,但与DataList也相差不远)里面所有的显示绑定数据的控件,都会显示DataSource里的数据,其余控件也将初始化成.aspx里设计的状态。

二、属性

1、DataSource

有DataBind的地方,就应该有DataSource。如果没有指定DataSource而执行DataBind,那DataGrid将什么也不会显示。

DataSource一般是DataSet、DataTable或者DataView。当然也可以绑定DataReader或者其他实现IEnumerable的类。

2、DataKeyField,DataKeys

当你在DataGrid中定位一行之后,肯定想知道这行在数据表里的位置,至少有五种方法可以做到这一点,设置DataGrid的DataKeyField就是这几种方法之一。

DataKeyField一般设置为数据表的Unique字段(否则就没意义了),通过DataKey可以得到这一行对应的关键字段的值。

DataKeys是DataKey的集合,通过行的索引来读取相应行的DataKey。

3、EditItemIndex,SelectedIndex,CurrentPageIndex,SelectedItem

这些属性都很好理解,看名字就知道是什么意思,需要注意的是,设置了EditItemIndex或者CurrentPageIndex后需要重新执行DataBind方法(当然,前面提到过,还需要设置DataSource)。

4、Columns

没什么好解释的,Columns就是Columns,列的集合,可以设置列的属性,包括Visible、HeaderText、FooterText、SortExpression等。

严重注意:自动生成的列,是不包含在Columns中的。只有在.aspx中显示声明的列和在代码中添加的列才会被包含在其中。

5、Items

俗话说,最后的都是最重要的,把Items作为最后一个属性来介绍,正式基于这样的理由。

Items是DataGridItem的集合,可以遍历当前DataGrid中显示数据的DataGridItem。

5.1、DataGridItem

每一个DataGridItem就是DataGrid中显示的一行,其中包括:

Header DataGrid 控件的标题部分

Item DataGrid 控件中的项

AlternatingItem DataGrid 控件中的交替项

SelectedItem DataGrid 控件中的选定项(由SelectedIndex设置,通过SelectedItem属性或者Items[SelectedIndex]来读取)

EditItem DataGrid 控件中处于编辑状态的项(由EditItemIndex设置,通过Items[EditItemIndex]来读取)

Separator DataGrid 控件中项之间的分隔符

Footer DataGrid 控件的脚注部分

Pager DataGrid 控件的页选择节

注意,DataGrid的Items属性中不会包含Header、Footer、Pager这三类DataGridItem的。

5.1.1、DataGridItem的属性

ItemIndex —— 得到行在Items中的索引

ItemType —— 返回行的类型,也就是上面列出的Header、Item、...、Pager

Cells —— 返回行包含的所有TableCell(不管是显示声明的,还是自动生成的,不管是可以看见的,还是隐藏掉的),通过TableCell,可以读取Cell中显示的文本、包含的控件

严重注意:只有BoundColumn列和自动生成列,才可以通过TableCell.Text属性读取显示的文本。HyperLinkColumn、ButtonColumn、EditCommandColumn都需要将目标控件转换成相应的控件。



“绿色IT 从我做起”圈子有奖活动
2007-9-11 10:502楼
[ 顶部 ]
 
redking
副版主  点击可查看详细


十二生肖之狗   双鱼座   行业勋章   技术勋章   诚信兄弟   中秋活动勋章  
帖子 2657
精华 0
无忧币 34792
积分 4345
阅读权限 140
来自 (保密)
注册日期 2006-7-11
最后登录 2008-9-5 离线

[查看资料]  [发短消息]  [Blog
[个人主页]    QQ       
发表于:2007-9-11 10:51 
比如:

假设DataGrid的第一列声明如下

<asp:HyperLinkColumn DataTextField="au_id" HeaderText="au_id" DataNavigateUrlField="au_id" DataNavigateUrlFormatString="Edit.aspx?id={0}"></asp:HyperLinkColumn>

读取的时候可以用:

//Items[0]表示第一行,Cells[0]表示第一列,Controls[0]表示Cell中的第一个控件(也只有这个控件可以用)

HyperLink link = (HyperLink)DataGrid1.Items[0].Cells[0].Controls[0]);

Response.Write(link.Text);

至于模板列(TemplateColumn),当然也可以通过DataGrid1.Items.Cells[j].Controls[n]来获取,然后转换成原来的控件类型再操作,但是还有个更好的办法,就是用FindControl来查找控件。

FindControl是System.Web.UI.Control的方法,可以根据子控件ID来查找子控件

比如:

假设DataGrid的某一列声明如下

<asp:TemplateColumn>

<ItemTemplate>

<asp:TextBox Runat="server" ID="txtID" Text=<%# DataBinder.Eval(Container.DataItem,"au_id") %>>

</asp:TextBox>

</ItemTemplate>

</asp:TemplateColumn>

读取方法:

TextBox txt = (TextBox)DataGrid1.Items[1].FindControl("txtID");

Response.Write(txt.Text);

注意:DataList中是没有Cell的

三、事件

1、ItemCommand、CancelCommand、DeleteCommand、EditCommand、UpdateCommand

也就是DataGrid中,点击Button、LinkButton后执行的事件,执行的事件取决于按钮的CommandName。其实最主要的一个是ItemCommand,而后面四个都只是ItemCommand的一小部分,

比如一个按钮的CommandName为"Cancel",当返回后,首先执行的是ItemCommand事件,然后才是CancelCommand事件。

2、PageIndexChanged

如果你的DataGrid是分页的,那当你在DataGrid上点击Pager上的1、2、3或者<、>时,就会激发这个事件。

在这个事件里面,你可以用e.NewPageIndex来读取要改变的页,然后赋值给DataGrid的CurrentPageIndex属性,最后不要忘了,还要设置DataSource,还要执行DataBind。

注意:DataList中没有这个事件,如果需要在DataList中分页,可以一段一段的读取数据,然后把当前段的数据绑定到DataList上。

3、ItemDataBound,ItemCreated

首先要说的是这两个事件的发生时间。

ItemDataBound嘛,只要执行了DataBind方法,就会马上激发这个事件。

ItemCreated呢,如果页面是第一次访问(Page.IsPostBack = false),那在第一次执行DataBind的时候,会先激发ItemCreated事件,也就是说,执行了DataBind后,首先会用ItemCreated来建立Header行,然后用ItemDataBound来绑定Header行,再用ItemCreated来建立第一行,再调用ItemDataBound来绑定第一行,也就是说ItemCreated和ItemDataBound是交替执行的。

页面返回时,也会执行ItemCreated

事件,在Page_Load之前,但是这时候就不会再执行ItemDataBound事件了。

所以,如果你想在DataGrid里动态添加什么控件,就需要在ItemCreated事件中,而不是在ItemDataBound事件中。


四、代码片断

1、DataGrid显示双层表头

假设你的DataGrid有三列,现在想将前两列作为"大类1",第三列作为"大类2",现在,你可以在ItemDataBound事件中加入下面的代码:



“绿色IT 从我做起”圈子有奖活动
2007-9-11 10:513楼
[ 顶部 ]
 
redking
副版主  点击可查看详细


十二生肖之狗   双鱼座   行业勋章   技术勋章   诚信兄弟   中秋活动勋章  
帖子 2657
精华 0
无忧币 34792
积分 4345
阅读权限 140
来自 (保密)
注册日期 2006-7-11
最后登录 2008-9-5 离线

[查看资料]  [发短消息]  [Blog
[个人主页]    QQ       
发表于:2007-9-11 10:51 
if (e.Item.ItemType == ListItemType.Header)

{

e.Item.Cells[0].ColumnSpan = 2;

e.Item.Cells[0].Text = "大类1</td><td>大类2</td></tr><tr><td>" + e.Item.Cells[0].Text;

}

用这个方法可以为任意添加新行。

2、设置绑定列或者自动生成列的编辑框宽度

请在你的ItemDataBound事件中加入一下代码:

if (e.Item.ItemType == ListItemType.EditItem)

{

for (int i = 0; i < e.Item.Cells.Count; i++)

{

TextBox txt = (TextBox)e.Item.Cells.Controls[0];

txt.Width = Unit.Pixel(50);

}

}

3、处理在DataGrid中的DropDownList的事件

DropDownList没有CommandName属性,所以不能用ItemCommand事件,不过你可以这样试试:

在DataGrid的模板列中加入的DropDownList控件

<aspropDownList runat="server" id="ddl" AutoPostBack="True" OnSelectedIndexChanged="ddl_SelectedIndexChanged" />

然后你在.aspx.cs中加入一个函数

protected void ddl_SelectedIndexChanged(object sender, System.EventArgs e) //一定要声明成protected或者public,不能是private的。

{

//在这里就可以加入其他代码

}

3.1、在上面的事件中怎样得到本行其他Cell的值呢?

我们知道,DataGrid完全是一个Table结构的控件,DataGrid包含DataGridItem,每个DataGridItem又包含TableCell,那么,我们就可以在TableCell的某个控件中,利用控件的Parent来得到TableCell,再利用TableCell的Parent,就可以得到DataGridItem了。

protected void ddl_SelectedIndexChanged(object sender, System.EventArgs e) //一定要声明成protected或者public,不能是private的。

{

DropDownList ddl = (DropDownList)sender;

TableCell cell = (TableCell)ddl.Parent;

DataGridItem item = (DataGridItem)cell.Parent;

Response.Write(item.Cells[0].Text);

}

4、怎样得到Header、Footer、Pager里的控件

方法一:在ItemCreated或者ItemDataBound中,具体代码就不在多写了

方法二:遍历DataGrid的所有Item(注意,不是遍历DataGrid1.Items下的Item)

foreach (DataGridItem item in DataGrid1.Controls[0].Controls)

{

if (item.ItemType == ListItemType.Header)

{

//用item.FindControl查找相应的控件

}

}

大家可能会注意到,这里有个DataGrid1.Controls[0].Controls,这表示,DataGrid1下,有一个子控件,这个子控件是DataGridTable类型,他下面才是DataGridItem集合

在DataList中,下面的子控件直接就是DataListItem了,而没有Table:

foreach (DataListItem item in DataList1.Controls)

{

//....

}



“绿色IT 从我做起”圈子有奖活动
2007-9-11 10:514楼
[ 顶部 ]
 
wfyang
新新人类  点击可查看详细



发帖王   在线王  
帖子 172
精华 0
无忧币 1265
积分 181
阅读权限 20
注册日期 2006-11-6
最后登录 2008-4-9 离线

[查看资料]  [发短消息]  [Blog
       
发表于:2007-9-11 11:52 
呵呵,哪里都能看到readking的身影



yangwenfeng@51cto.com
2007-9-11 11:525楼
[ 顶部 ]
     
论坛跳转:  

| | |

| | |

| | |

标记已读 · 删除论坛Cookies · 文本版 · WAP
 
| 诚征版主 | 版主堂 | 意见建议 | 大史记 | 论坛地图
Copyright©2005-2008 51CTO.COM  Powered by Discuz!
本论坛言论纯属发布者个人意见,不代表51CTO网站立场!如有疑义,请与管理员联系。
京ICP备05051492号