No.1 数据源:
对于GridView来说,只要是序列化的数据都可以作为数据源.比如对象数组/XML/Table等等,只要你能想象到的,可以转化成一张表的东西.
如果图省心的话,可以配合DataSource控件来使用它,那么对数据的操作就可以集中在DataSource中处理,双剑合璧挖,省时又省心.
其绑定数据源的步骤就是:1.指定数据源:gridview.Datasource=xxx;2.绑定数据源:gridview.DataBind();
No.2 数据的绑定:
GridView在我们绑定数据源之后会默认自动根据数据生成列,但是有时候,我们会手动指定数据源而不用DataSource控件,并且需要更多样化的数据绑定和控制,所以,使用模板列来绑定数据,并对模版内的控件定位就成了关键:(这里我把用GridView自带列绑定数据省略掉了,如果有时间,我会把这里放在本文的最下面的附录里)
1.设置模板列
在Design(设计)模式下,GridView右上角有个小三角,点击它就可以对GridView进行更多操作,比如对列进行编辑;如果添加了模板列的话,还可以在这里对模板列进行编辑.
在"显示"这里,点击下拉列表,选择Item Template(这里是主要的显示处,所放进来的东西会在GridView的普通状态下显示),我们可以随便往里面填什么(基本上所有可以显示数据的控件都可以放进来帮助我们绑定并显示数据).
比如我们拖进来一个Label,然后点击Label右上角的小三角就可以设置其的数据绑定了.
如果用一个设置好的DataSource控件做数据源,那么就可以直接在里面选择要绑定的字段及其显示格式,系统帮我们自动生成代码;
如果是自己指定数据源.....那么我们就只好自己来设置绑定了,可以在这里直接输入Eval("需要显示的字段"),也可以切换到代码,在里面写.对于Label来说,可能的写法是:<asp:Label ID="Label1" runat="server" Text='<%# Eval("id") %>'></asp:Label>.
自己书写<%# Eval("id") %>最大的好处就是:我们可以任意在里面填写我们所需要的代码!比如:<%# Convert.ToString(Convert.ToInt32( Eval("id") )+100)%>
瞧,这意味着我们可以对该绑定的数据进行一定的修饰,然后再显示.如果该数据控件是一个类似GridView的可以帮定数据列的,那么我们甚至可以给它指定一个返回数据源的函数!
在"显示"这里,点击下拉列表,选择EditItem Template(所放进来的东西会在GridView的编辑状态下显示--即GridView.EditIndex等于该行时),我们需要往里面放我们希望在编辑该数据时要显示的东西,比如一个TextBox(在这里,同样可以给控件指定要绑定的数据).
代码可能是这样的:<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("id") %>'></asp:TextBox>
然后GridView里面的全部代码可能是这样的:
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("id") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Columns>
给GridView添加一个RowEditing事件:
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
this.GridView1.EditIndex = e.NewEditIndex;
}
运行一下,显示正常,点击Edit会发现显示的数据被放进了一个TexBox,这样我们就可以对它进行编辑了.
2.在GridView的RowDataBound事件中,设置详细的绑定数据
在上面我们使用模板列来控制数据绑定以后基本上可以控制大部分数据的详细显示了.但是可能有人觉得这样写不太好看(页面和代码根本没分离嘛),或者我们在GridView里使用了UserControl而带来的绑定错误(因为在GridView给控件绑定数据时,UserControl还没有初始化)等原因,所以可以在这个事件里进行详细的绑定设置.
从名字上就可以知道,该事件是GridView的一行被绑定后才触发的.由于具体的行绑定涉及到行内数据的定位,所以就放在下面来说明如何使用RowDataBound,在这里,我们大概说下它的过程:首验证传回的e.Row是否被创建完全,然后从e.Row里用FindControl(ControlID)来获取ID为ControlID的控件,最后给控件赋值即可.需要注意的是,如果用的是GridView自带的列,则在RowDataBound中就是不同的方法来寻找了.
由于数据的绑定完全在后台代码中实现,我们可以更加自由地去修改和绑定数据了.
No.3 GriView中的控件/数据定位:
在GridView中寻找一个数据并不是简简单单地一个this.GridView1.XXX那么简单,因为毕竟我们在后台写代码的时候,GridView里面的数据/数据模板还没有生成呐.所以一般来说,我们采用的方法是先确定该数据/数据模板所在的行,然后根据其类型来从该行提取它(在这里我们就可以看到,这也是一个假定该行已经被完全创建,且该行包含我们要找的数据/数据模板----因此使用的时候请首先确认执行该代码前,代码所需要的行已经被创建).
要获取GridView自生成的列,可以用this.GridView1.Rows[index].Cells[index].Text;
而模版列,则要用this.GridView1.Rows[index].Cells[index].FindControl(string ControlID)或者是this.GridView1.Rows[index].FindControl(string ControlID).
检查GridView的行是否被创建,可以用Row.RowType == DataControlRowType.DataRow(其中Row是我们要检验的GridView行).
下面介绍常用的2种定位,各有各的优缺点,使用事件常常得到的是一个行,而使用Button控件的数据绑定则可以根据绑定的不同得到特定的数据.
1.使用GridView自带事件进行定位:
下面我列出可能用到的事件(这里默认控件名为GridView1)
protected void GridView1_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
//用GridView的Select列时,可以使用这个方法
//e.NewSelectedIndex;//当前要选择的行,获取的是GridView当前页的index
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
//this.GridView1.SelectedValue.ToString();
//当前要选择的行的DataKeys,获取的是GridView当前页的DataKeys,
//比如可以设置GridView的DataKeys是数据源里的"ID"那么这里获取的就是当前选中行的数据的ID.
//需要注意的是,SelectedValue只有在SelectedIndexChanged中才有值,其他时候是null;
}
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//e.RowIndex;//当前要提交的行,获取的是GridView当前页的index
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//e.NewEditIndex;//当前要编辑的行,获取的是GridView当前页的index
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//e.RowIndex;//当前要删除的行,获取的是GridView当前页的index
}
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
//e.RowIndex;//当前要撤消编辑的行,获取的是GridView当前页的index
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
//e.NewPageIndex;//当前要到的页,获取的是GridView要切换页的index
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != GridView1.EditIndex)
{
//e.Row;//当前已经生成,并绑定好数据的行;
}
}
2.使用Button中的CommandArgument属性来绑定ID,进而获取要编辑、删除、提交、选择的行.
比如可能的代码是这样的:<asp:Button ID="Button1" runat="server" CommandArgument='<%# Eval("id") %>'
onclick="Button1_Click" Text="Button" />
然后在Button1_Click这个事件中,我们就可以用((Button)sender).CommandArgument来获得绑定的数据
3.使用GridView.XXX来进行定位.
问题回来了,现在我们要讨论的是如何用GridView这种常用而又熟悉的方式来从GridView中获取我们想要的数据.
在GridView中,可以存放2种数据:一种可以显示出来的,呈现给我们的是一个表格形式,那就是我们通常所使用GridView.Row或者Column来获取到的;一种是不显示的,但是我们可以在后台使用,可以使用GridView.DataKeys来设置和获取其值;
不管是哪种数据,只要不是GridView的属性,就需要我们在GridView完全生成以后才能获取.
1)数据表格
就像前面所说,GridView仅仅将数据生成了一个表格,所以获取的方式无非就是GridView.Row(GridView.Column主要用来设置整个列的属性,所以一般不用来获取里面的值),下面就是一个例子,我给每行的第2列中的btnAdd这个Button添加一个小属性:
foreach (GridViewRow gr in GridView)
{
((Button)gr.Cells[1].FindControl("Button")).Attributes.Add("onclick", "alert('Clicked me!')");
}
2)DataKeys
如果是DataKeys中的数据,那么就可以直接使用GridView.DataKeys[编号或者绑定的Key的名称]来获取.比如我在开始的时候设置GridView.DataKeyNames="id";那么等到所有数据绑定完成后,就可以用GridView.DataKeys["id"]来获取该行数据id的值了.
这样的好处是显而易见的,如果我希望能获取该行的特定字段值,而又不让其在页面上显示,那么这种方法最好不过了.
基本先说到这儿,其他的以后再加,欢迎大家讨论和提点意见