GridView实战二:使用ObjectDataSource数据源控件
2011-12-17 15:30
417 查看
前言:
ObjectDataSource数据源控件优点甚多,确实令人爱不惜手,但不支持重绑定这一项确实让人失望。下面的实战二将通过ObjectDataSource配合GridView来实现删、改、分页、排序,并分析使用cache后排序失灵的原因。
实战:
1.效果:
图1.显示状态
图2.编辑状态
2.代码:
.aspx
说明:
1.因用了数据源控件,所以Name在编辑状态时使用<%#Bind("Name")%>来实现双向通讯的绑定
2.因为没有添加的功能,所以用了asp:CommandField来实现编辑、删除等按钮的功能。
3.排序功能上只要在ods上设定SortParameterName,它的值就是SelectMethod中关于排序的参数的名称,然后设定GridView的AllowSorting为true就ok了。排序按钮上依然用到GridView内置的CommandName——Sort,然后CommandArgument设为要排序的字段名,至于排序的方向由ObjectDataSource负责,省心多了。
.aspx.cs代码
说明:
1.看到behind code是不是发现代码量少了很多呢?这就是用ods的好处了。
2.在更新操作时,因为Country、Sex和Hobby都没有和ods作双向绑定,所以要自己获取并写入到ods的InputParameters中,然后ods就会调用已经设置好的UpdateMethod了。
数据操作类
说明:
1.GetRecord方法绑定到ods的SelectMethod上,因为启用分页和排序功能,所以参数数组中必须有maximumRows(每页记录数), startRowIndex(当前页首条记录在整个数据集中的索引), sortExpression(排序表达式,首次加载页面时为空字符串,postback时含排序字段和排序方向)。
3.数据缓存
ods可以启用cache,该cache为应用程序级的,就是多个画面的ods只要SelectMethod和SelectCountMethod、Select参数一样就可以共享缓存中的数据,在Cache有效时进行Select操作将会先根据前面说的三个要素从Cache中获取数据,如果没有才执行SelectMethod方法。注意不同的要素组合会各自对应一份缓存的数据,当第二次请求时就直接读缓存。
就是因为这样问题就来了,如果启用了cache那么上面的排序功能就会失效,而其他功能依然正常。原因在于排序操作是在SelectMethod中实现,而在Cache生效时程序根本就不执行SelectMethod方法,除非说内存不足或其他原因令cache不够大来保存数据而被迫执行SelectMethod方法。对于该问题目前还没找到解决的方法,望大哥们来告诉我啦^_^
好消息:对于上面的问题终于找到了解决方法,就是自定义一个缓存层而不使用ods附带的缓存功能。具体请看:/article/4741014.html
ObjectDataSource数据源控件优点甚多,确实令人爱不惜手,但不支持重绑定这一项确实让人失望。下面的实战二将通过ObjectDataSource配合GridView来实现删、改、分页、排序,并分析使用cache后排序失灵的原因。
实战:
1.效果:
图1.显示状态
图2.编辑状态
2.代码:
.aspx
<asp:ObjectDataSource runat="server" ID="ods" EnablePaging="true" TypeName="OdsDataManager" SelectCountMethod="GetRecordCount" SelectMethod="GetRecord" UpdateMethod="UpdateRecord" DeleteMethod="DelRecord" OnUpdating="ods_OnUpdating" SortParameterName="sortExpression"> </asp:ObjectDataSource> <asp:GridView runat="server" ID="gv" DataSourceID="ods" AutoGenerateColumns="false" AllowPaging="true" PageSize="1" AllowSorting="true" DataKeyNames="ID" OnRowDataBound="gv_OnRowDataBound"> <HeaderStyle BackColor="graytext" /> <Columns> <asp:TemplateField> <HeaderStyle Width="20%" /> <HeaderTemplate> <asp:LinkButton runat="server" ID="lbtnSortName" Text="Name" CommandName="Sort" CommandArgument="Name"> </asp:LinkButton> </HeaderTemplate> <ItemTemplate><%#Eval("Name") %></ItemTemplate> <EditItemTemplate> <asp:TextBox runat="server" ID="tbxName" Text='<%#Bind("Name") %>'></asp:TextBox> <asp:RegularExpressionValidator runat="server" ID="revName" ControlToValidate="tbxName" ValidationExpression="[a-zA-Z]+" ErrorMessage="Please input your English name!" Display="Dynamic"> </asp:RegularExpressionValidator> <asp:RequiredFieldValidator runat="server" ID="rfvName" ControlToValidate="tbxName" ErrorMessage="Please input your name" Display="Dynamic"> </asp:RequiredFieldValidator> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderStyle Width="10%"/> <HeaderTemplate> <asp:LinkButton runat="server" ID="lbtnSortSex" Text="Sex" CommandName="Sort" CommandArgument="Sex"> </asp:LinkButton> </HeaderTemplate> <ItemTemplate> <asp:RadioButtonList Enabled="false" runat="server" ID="rblSexShow" RepeatDirection="Horizontal" RepeatColumns="2"> </asp:RadioButtonList> </ItemTemplate> <EditItemTemplate> <asp:RadioButtonList runat="server" ID="rblSexEdit" RepeatDirection="Horizontal" RepeatColumns="2"> </asp:RadioButtonList> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderStyle Width="20%"/> <HeaderTemplate> <asp:LinkButton runat="server" ID="lbtnSortCountry" Text="Country" CommandName="Sort" CommandArgument="Country"> </asp:LinkButton> </HeaderTemplate> <ItemTemplate><%#Eval("Country")%></ItemTemplate> <EditItemTemplate> <asp:DropDownList runat="server" ID="ddlCountry"></asp:DropDownList> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderStyle Width="20%"/> <HeaderTemplate>Hobby</HeaderTemplate> <ItemTemplate><%#Eval("Hobby") %></ItemTemplate> <EditItemTemplate> <asp:CheckBoxList runat="server" ID="cbxlHobby" RepeatDirection="Horizontal" RepeatColumns="5"> </asp:CheckBoxList> </EditItemTemplate> </asp:TemplateField> <asp:CommandField ShowDeleteButton="true" DeleteText="Delete" ShowEditButton="true" EditText="Edit" /> </Columns> <PagerSettings Visible="true" /> <PagerStyle Font-Size="12px"/> <PagerTemplate> <div style="float:left;margin-left:15px;color:#999;line-height:20px"> 当前第<%#this.gv.PageIndex+1 %>/<%#this.gv.PageCount %>页 </div> <div style="float:right;margin-right:15px;color:#999;line-height:20px">页</div> <div style="float:right"> <asp:DropDownList runat="server" ID="ddlPaging" AutoPostBack="true" OnSelectedIndexChanged="ddlPaging_OnSelectedIndexChanged"> </asp:DropDownList> </div> <div style="float:right;color:#999;line-height:20px">跳转到第</div> </PagerTemplate> </asp:GridView>
说明:
1.因用了数据源控件,所以Name在编辑状态时使用<%#Bind("Name")%>来实现双向通讯的绑定
2.因为没有添加的功能,所以用了asp:CommandField来实现编辑、删除等按钮的功能。
3.排序功能上只要在ods上设定SortParameterName,它的值就是SelectMethod中关于排序的参数的名称,然后设定GridView的AllowSorting为true就ok了。排序按钮上依然用到GridView内置的CommandName——Sort,然后CommandArgument设为要排序的字段名,至于排序的方向由ObjectDataSource负责,省心多了。
.aspx.cs代码
public partial class Default2 : System.Web.UI.Page { private OdsDataManager dm = new OdsDataManager(); protected void Page_Load(object sender, EventArgs e) { } protected void gv_OnRowDataBound(object sender, GridViewRowEventArgs e) { DataRowView drv = e.Row.DataItem as DataRowView; if (e.Row.RowType == DataControlRowType.DataRow) { //显示时 if (this.gv.EditIndex == -1) { //设置性别 RadioButtonList rbl = e.Row.FindControl("rblSexShow") as RadioButtonList; rbl.Items.Add(new ListItem("Male", "M")); rbl.Items.Add(new ListItem("Female", "F")); if ((drv["Sex"] as string).ToLower().Equals("m")) rbl.Items[0].Selected = true; else rbl.Items[1].Selected = true; } //修改时: else if (e.Row.RowIndex == this.gv.EditIndex) { //性别 RadioButtonList rbl = e.Row.FindControl("rblSexEdit") as RadioButtonList; rbl.Items.Add(new ListItem("Male", "M")); rbl.Items.Add(new ListItem("Female", "F")); if ((drv["Sex"] as string).ToLower().Equals("m")) rbl.Items[0].Selected = true; else rbl.Items[1].Selected = true; //国籍 DropDownList ddlCountry = e.Row.FindControl("ddlCountry") as DropDownList; DataTable countryDt = dm.GetCountry(); ListItem li = null; for (int i = 0; i < countryDt.Rows.Count; ++i) { string cn = countryDt.Rows[i]["cn"] as string; li = new ListItem(cn, cn); if (cn.Equals(drv["Country"] as string)) li.Selected = true; ddlCountry.Items.Add(li); } //兴趣 CheckBoxList cbl = e.Row.FindControl("cbxlHobby") as CheckBoxList; DataTable hobbyDt = dm.GetHobby(); string hobbys = drv["Hobby"] as string; ListItem hobbyLi = null; string hstr = string.Empty; for (int i = 0; i < hobbyDt.Rows.Count; i++) { hstr = hobbyDt.Rows[i]["hobby"] as string; hobbyLi = new ListItem(hstr, hstr); if (hobbys.IndexOf(hstr) >= 0) hobbyLi.Selected = true; cbl.Items.Add(hobbyLi); } } } else if (e.Row.RowType == DataControlRowType.Pager) { //绑定分页控件 DropDownList ddlPaging = e.Row.FindControl("ddlPaging") as DropDownList; for (int i = 0; i < this.gv.PageCount; i++) { ddlPaging.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i))); } ddlPaging.SelectedIndex = this.gv.PageIndex; } } /// <summary> /// 分页控件的OnSelectedIndexChanged /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void ddlPaging_OnSelectedIndexChanged(object sender, EventArgs e) { this.gv.PageIndex = (sender as DropDownList).SelectedIndex; } protected void ods_OnUpdating(object sender, ObjectDataSourceMethodEventArgs e) { string Sex = (this.gv.Rows[this.gv.EditIndex].FindControl("rblSexEdit") as RadioButtonList).SelectedValue; string Country = (this.gv.Rows[this.gv.EditIndex].FindControl("ddlCountry") as DropDownList).SelectedValue; System.Text.StringBuilder hobbys = new System.Text.StringBuilder(); foreach (ListItem li in (this.gv.Rows[this.gv.EditIndex].FindControl("cbxlHobby") as CheckBoxList).Items) { if (li.Selected) hobbys.Append(li.Value+","); } if (hobbys.Length >= 2) hobbys.Remove(hobbys.Length - 1, 1); e.InputParameters.Add("Sex", Sex); e.InputParameters.Add("Country", Country); e.InputParameters.Add("Hobby",hobbys.ToString()); } }
说明:
1.看到behind code是不是发现代码量少了很多呢?这就是用ods的好处了。
2.在更新操作时,因为Country、Sex和Hobby都没有和ods作双向绑定,所以要自己获取并写入到ods的InputParameters中,然后ods就会调用已经设置好的UpdateMethod了。
数据操作类
public class OdsDataManager { private static DataTable dt = null;//用户记录 private static DataTable countryDt = null;//国籍 private static DataTable hobbyDt = null;//兴趣 public OdsDataManager() { if (dt == null) { dt = new DataTable(); dt.Columns.Add("ID"); dt.Columns.Add("Name"); dt.Columns.Add("Sex"); dt.Columns.Add("Country"); dt.Columns.Add("Hobby"); //Default Data dt.Rows.Add(new object[] { 1, "Mary", "F", "China", "Cooking,Music" }); dt.Rows.Add(new object[] { 2, "John", "M", "China", "Tennis" }); } if (countryDt == null) { countryDt = new DataTable(); countryDt.Columns.Add("cn"); //Default Data countryDt.Rows.Add(new object[] { "China" }); countryDt.Rows.Add(new object[] { "French" }); countryDt.Rows.Add(new object[] { "America" }); countryDt.Rows.Add(new object[] { "Afria" }); countryDt.Rows.Add(new object[] { "Japan" }); } if (hobbyDt == null) { hobbyDt = new DataTable(); hobbyDt.Columns.Add("hobby"); //Default Data hobbyDt.Rows.Add(new object[] { "Cooking" }); hobbyDt.Rows.Add(new object[] { "Music" }); hobbyDt.Rows.Add(new object[] { "Reading" }); hobbyDt.Rows.Add(new object[] { "Movies" }); hobbyDt.Rows.Add(new object[] { "Tennis" }); } } public DataTable GetRecord(int maximumRows, int startRowIndex, string sortExpression) { //排序 if(!string.IsNullOrEmpty(sortExpression)) { dt.DefaultView.Sort = sortExpression; } DataRow[] drs = dt.Select(); DataTable dt1 = dt.Clone(); for (int i = startRowIndex; i < startRowIndex+maximumRows && i<drs.Length; i++) { dt1.Rows.Add(drs[i].ItemArray); } return dt1; } public int GetRecordCount() { return dt.Rows.Count; } public bool UpdateRecord(int ID, string Name, string Sex, string Country, string Hobby) { bool result = false; DataRow[] drs = dt.Select("ID=" + ID); if (drs.Length == 1) { drs[0]["Name"] = Name; drs[0]["Sex"] = Sex; drs[0]["Country"] = Country; drs[0]["Hobby"] = Hobby; result = true; } return result; } public bool DelRecord(int ID) { bool result = false; DataRow[] drs = dt.Select("ID=" + ID); if (drs.Length == 1) { dt.Rows.Remove(drs[0]); result = true; } return result; } public DataTable GetCountry() { return countryDt; } public DataTable GetHobby() { return hobbyDt; } }
说明:
1.GetRecord方法绑定到ods的SelectMethod上,因为启用分页和排序功能,所以参数数组中必须有maximumRows(每页记录数), startRowIndex(当前页首条记录在整个数据集中的索引), sortExpression(排序表达式,首次加载页面时为空字符串,postback时含排序字段和排序方向)。
3.数据缓存
ods可以启用cache,该cache为应用程序级的,就是多个画面的ods只要SelectMethod和SelectCountMethod、Select参数一样就可以共享缓存中的数据,在Cache有效时进行Select操作将会先根据前面说的三个要素从Cache中获取数据,如果没有才执行SelectMethod方法。注意不同的要素组合会各自对应一份缓存的数据,当第二次请求时就直接读缓存。
就是因为这样问题就来了,如果启用了cache那么上面的排序功能就会失效,而其他功能依然正常。原因在于排序操作是在SelectMethod中实现,而在Cache生效时程序根本就不执行SelectMethod方法,除非说内存不足或其他原因令cache不够大来保存数据而被迫执行SelectMethod方法。对于该问题目前还没找到解决的方法,望大哥们来告诉我啦^_^
好消息:对于上面的问题终于找到了解决方法,就是自定义一个缓存层而不使用ods附带的缓存功能。具体请看:/article/4741014.html
相关文章推荐
- GridView实战二:使用ObjectDataSource数据源控件(自定义缓存机制实现Sort)
- GridView控件在不使用数据源控件时,实现排序和分页
- WCF开发实战系列二:使用IIS发布WCF服务
- 使用TinySpider实战抓取自己博客中的内容
- iOS项目开发实战——使用CALayer和定时器实现进度条
- 在GridView中使用DropDownList模板列
- .NET 使用GridView控件的SelectIndexChanging事件
- Go实战--使用golang开发Windows Gui桌面程序(lxn/walk)
- Centos 7部署docker环境、基本命令使用及简单实战
- 如何使用GridView实现不同数量显示图片不同的大小
- 在线医疗平台开发实战04-AutoMapper使用及无法引用问题解决
- Android实战——GreenDao3.2的使用,爱不释手
- APP开发实战156-Volley网络库的简介和使用
- Java Socket实战之七 使用Socket通信传输文件
- C#2.0中 GridView日期列使用DataFormatString="{0:d}"
- spring 入门实战(二)一个简单的使用案例
- gridview使用经验
- MP实战系列(一)之入门框架搭建和使用
- Unity游戏开发使用Assetbundle加载场景实战
- Docker实战:使用Dockerfile创建带Apache服务并支持ssh的Centos Docker镜像