开发背景
最近在独立开发一款OA管理系统,使用的技术是Asp.Net,其中使用到了GridView,分享一下它的使用
基本数据绑定
可以双击控件在光标所在处创建控件,也可以拖拽创建
准备一组数据
protected void Bind()
{
GridView1.DataSource = new BindingList<User>(Users);
GridView1.DataBind();
}
自定义一个方法,用于绑定数据
protected void Page_Load(object sender, EventArgs e)
{
Bind();
}
在页面加载时调用
在页面显示的效果
自定义列数据绑定
protected void Page_Load(object sender, EventArgs e)
{
GridView1.AutoGenerateColumns = false;
Bind();
}
可以通过AutoGenerateColumns 属性让控件不自动创建列,要放在数据绑定前使用
可以将光标移到GridView上单击小箭头展开
展开后单击编辑列,弹出字段对话框
可以在可用字段中选择BoundField 后点击添加
DataField设置该字段绑定的字段
HeaderText设置该字段的列名
如果不希望Id显示可以设置Visible属性为false
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:BoundField DataField="Id" HeaderText="编号" Visible="False"></asp:BoundField>
<asp:BoundField DataField="UserName" HeaderText="用户名"></asp:BoundField>
<asp:BoundField DataField="PassWord" HeaderText="密码"></asp:BoundField>
</Columns>
</asp:GridView>
最终生成的代码片段
页面显示的结果
编辑模板
进入编辑列选择CommandField 展开后选择编辑、更新、取消 单击添加
页面显示
单击编辑可能会报错,通过异常信息可以看出是因为没有绑定事件RowEditing 所造成的
<asp:GridView ID="GridView1" runat="server" OnRowEditing="GridView1_RowEditing">
<Columns>
<asp:BoundField DataField="Id" HeaderText="编号" Visible="False"></asp:BoundField>
<asp:BoundField DataField="UserName" HeaderText="用户名"></asp:BoundField>
<asp:BoundField DataField="PassWord" HeaderText="密码"></asp:BoundField>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
</Columns>
</asp:GridView>
绑定事件(代码提示在按住截图快捷键后有点模糊)
绑定事件后并且后台代码中生成了方法,打开页面,单击编辑就可以进入编辑状态
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
Bind();
}
如果报了异常可以在方法中编写以上代码
EditIndex用于设置或获取GridView控件要编辑的行的下标
而该方法的第二个参数就提供了编辑行事件所需要的数据,其中包括了NewEditIndex
NewEditIndex可以理解为获取单击了编辑按钮的行的索引
如果需要单击两次编辑按钮才会进入编辑事件,可以调用之前写的Bind方法
博主刚刚在调试下绑定了事件,但是调试时是不能编辑后台代码的,所以没有生成绑定事件的方法
可以停止调试后在绑定事件
更新
先绑定RowUpdating 事件
<asp:GridView ID="GridView1" runat="server" OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:BoundField DataField="Id" HeaderText="编号" Visible="False"></asp:BoundField>
<asp:BoundField DataField="UserName" HeaderText="用户名"></asp:BoundField>
<asp:BoundField DataField="PassWord" HeaderText="密码"></asp:BoundField>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
</Columns>
</asp:GridView>
此时的代码片段
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
string userName = e.NewValues[0].ToString();
string passWord = e.NewValues[1].ToString();
}
可以通过第二个参数的NewValue获取更新的数据,可以通过下标访问
此时获取的数据和原数据是一样的。
在了解了Asp.Net的生命周期以后得知,每次执行事件前,都要进行一次回发
protected void Page_Load(object sender, EventArgs e)
{
GridView1.AutoGenerateColumns = false;
Bind();
}
而Page_Load事件每次回发时都要执行一次,所以在执行更新事件前,更新的数据又被绑定的数据给覆盖了。
protected void Page_Load(object sender, EventArgs e)
{
GridView1.AutoGenerateColumns = false;
if (!Page.IsPostBack)
{
Bind();
}
}
Page.IsPostBack可以用于判断当前是否是回发,为true则是回发,反之是第一次呈现页面
我们只需要在第一次呈现页面时绑定数据即可
再次进入GridView1_RowUpdating 事件时,能够成功的获取更新后的值
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
string userName = e.NewValues[0].ToString();
string passWord = e.NewValues[1].ToString();
Users[e.RowIndex].UserName = userName;
Users[e.RowIndex].PassWord = passWord;
GridView1.EditIndex = -1;
Bind();
}
RowIndex可以获取正在编辑的行的下标,已知集合的数据和GridView控件的值一致时,可以直接使用来更新数据
EditIndex设为-1可以取消编辑状态(要在Bind前面使用)
更新数据后调用Bind方法即可完成更新数据
不过数据不能永久保存,需要永久保存要存入数据库中
页面更新成功
取消编辑
进入编辑状态后,单击取消时会报异常,本次异常也是一样,需要绑定RowCancelingEdit 事件
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1;
Bind();
}
设置EditIndex属性为-1退出编辑状态,然后在调用Bind方法绑定控件
(不调用Bind方法不会立刻退出编辑状态,并且再次单击取消时,单元格为空)
删除
单击编辑列,打开字段对话框,展开CommandField 选中删除,单击添加按钮,添加删除列
页面效果
需要绑定事件RowDeleting 事件
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Users.RemoveAt(e.RowIndex);
Bind();
}
将对应数据删除后,重新绑定数据即可
自定义编辑模板
List<User> Users = new List<User>()
{
new User(){ Id=1, UserName="张三", PassWord="1234", Gender=0 },
new User(){ Id=2, UserName="李四", PassWord="12345", Gender=1 },
new User(){ Id=3, UserName="王五", PassWord="123456", Gender=0 }
};
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string PassWord { get; set; }
public int Gender { get; set; }
}
<asp:GridView ID="GridView1" runat="server" OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating" OnRowCancelingEdit="GridView1_RowCancelingEdit" OnRowDeleting="GridView1_RowDeleting">
<Columns>
<asp:BoundField DataField="Id" HeaderText="编号"></asp:BoundField>
<asp:BoundField DataField="UserName" HeaderText="用户名"></asp:BoundField>
<asp:BoundField DataField="PassWord" HeaderText="密码"></asp:BoundField>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
<asp:CommandField ShowDeleteButton="True"></asp:CommandField>
</Columns>
</asp:GridView>
为了演示添加了性别字段,并且将id的visible属性给删除,默认显示
将需要自定义编辑模板的字段选中,单击右下角将此字段转换为 TemplateField ,这里需要自定义编号和性别
选中左下角设计或拆分,选中GridView控件,单击小箭头即可弹出GridView任务,点击编辑模板
进入编辑模板后点击下拉框,即可看到转换为编辑模板的字段
ItemTemplate:定义该列默认的内容和样式
AlternatingItemTemplate:定义交替行的内容和样式,如果没有,默认使用ItemTemplate
EditItemTemplate:定义编辑列的内容和样式
HeaderTemplate:定义该列的头部的内容和样式
FooterTemplate:定义该列的页脚的内容和外观
id这列的编辑列默认为文本框,需要将他设置为label
单击小箭头后,点击编辑
进入DataBindings对话框,键入代码表达式
代码表达式可以有两种方法进行绑定
1.Bind(“数据源字段名”):Bind方法是一种双向绑定,即和控件绑定也和数据源绑定,所以不能对Bind方法的数据进行操作
2.Eval(“数据源字段名”):Eval方法是一种单向绑定,即数据是只读的,所以可以对Eval方法的数据进行操作
对性别就要使用Eval单向绑定,因为我们要对性别的数据进行操作
这就是使用Bind对数据进行操作的异常信息
当进入编辑状态时,我们希望性别是一个下拉框
创建下拉框
编辑下拉框
绑定SelectedValue属性
就可以实现编辑状态性别变为下拉框
获取单元格中的控件
点击更新后,会进入RowUpdating事件,可以通过方法的第二个参数获取数据,但是不能够获取下拉框的值,所以需要获取控件来取值
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
string userName = e.NewValues[0].ToString();
string passWord = e.NewValues[1].ToString();
DropDownList ddl = GridView1.Rows[e.RowIndex].Cells[3].FindControl("ddl_Gender") as DropDownList;
int val = Convert.ToInt32(ddl.SelectedValue);
Users[e.RowIndex].UserName = userName;
Users[e.RowIndex].PassWord = passWord;
Users[e.RowIndex].Gender = val;
GridView1.EditIndex = -1;
Bind();
}
通过方法提供的第二个参数取得当前更新的行的下标,已知性别列是在第四个单元格,使用FindControl方法传入id取得下拉框,最后通过as转换类型
总结
GridView很大程度的方便了我们的开发,是一个不可多得的控件。