GridView实战二:使用ObjectDataSource数据源控件

前言:

  ObjectDataSource数据源控件优点甚多,确实令人爱不惜手,但不支持重绑定这一项确实让人失望。下面的实战二将通过ObjectDataSource配合GridView来实现删、改、分页、排序,并分析使用cache后排序失灵的原因。

实战:

1.效果:

图1.显示状态

图2.编辑状态

2.代码:

.aspx

 1 <asp:ObjectDataSource runat="server" ID="ods" EnablePaging="true" TypeName="OdsDataManager"
 2         SelectCountMethod="GetRecordCount" SelectMethod="GetRecord" UpdateMethod="UpdateRecord"
 3         DeleteMethod="DelRecord" OnUpdating="ods_OnUpdating" SortParameterName="sortExpression">
 5      </asp:ObjectDataSource>
 6     <asp:GridView runat="server" ID="gv" DataSourceID="ods" AutoGenerateColumns="false"
 7              AllowPaging="true" PageSize="1" AllowSorting="true" DataKeyNames="ID"
 8              OnRowDataBound="gv_OnRowDataBound">
 9              <HeaderStyle BackColor="graytext" />
10             <Columns>
11                 <asp:TemplateField>
12                     <HeaderStyle Width="20%" />
13                     <HeaderTemplate>
14                         <asp:LinkButton runat="server" ID="lbtnSortName" Text="Name" CommandName="Sort" CommandArgument="Name">
15                         </asp:LinkButton>
16                     </HeaderTemplate>
17                     <ItemTemplate><%#Eval("Name") %></ItemTemplate>
18                     <EditItemTemplate>
19                         <asp:TextBox runat="server" ID="tbxName" Text='<%#Bind("Name") %>'></asp:TextBox> 
20                         <asp:RegularExpressionValidator runat="server" ID="revName" ControlToValidate="tbxName"
21                              ValidationExpression="[a-zA-Z]+" ErrorMessage="Please input your English name!" Display="Dynamic">
22                         </asp:RegularExpressionValidator>
23                         <asp:RequiredFieldValidator runat="server" ID="rfvName" ControlToValidate="tbxName"
24                             ErrorMessage="Please input your name" Display="Dynamic">
25                         </asp:RequiredFieldValidator> 
26                     </EditItemTemplate>
27                 </asp:TemplateField> 
28                 <asp:TemplateField>
29                     <HeaderStyle Width="10%"/>
30                     <HeaderTemplate>
31                         <asp:LinkButton runat="server" ID="lbtnSortSex" Text="Sex" CommandName="Sort" CommandArgument="Sex">
32                         </asp:LinkButton> 
33                     </HeaderTemplate> 
34                     <ItemTemplate>
35                         <asp:RadioButtonList Enabled="false" runat="server" ID="rblSexShow" RepeatDirection="Horizontal" 
36                             RepeatColumns="2">
37                         </asp:RadioButtonList>
38                     </ItemTemplate> 
39                     <EditItemTemplate>
40                          <asp:RadioButtonList runat="server" ID="rblSexEdit" RepeatDirection="Horizontal" RepeatColumns="2">
41                          </asp:RadioButtonList>
42                     </EditItemTemplate> 
43                 </asp:TemplateField>
44                 <asp:TemplateField>
45                     <HeaderStyle Width="20%"/>
46                     <HeaderTemplate>
47                         <asp:LinkButton runat="server" ID="lbtnSortCountry" Text="Country" CommandName="Sort" CommandArgument="Country">
48                         </asp:LinkButton>
49                     </HeaderTemplate> 
50                     <ItemTemplate><%#Eval("Country")%></ItemTemplate> 
51                     <EditItemTemplate>
52                         <asp:DropDownList runat="server" ID="ddlCountry"></asp:DropDownList>
53                     </EditItemTemplate> 
54                 </asp:TemplateField>
55                 <asp:TemplateField>
56                     <HeaderStyle Width="20%"/>
57                     <HeaderTemplate>Hobby</HeaderTemplate>
58                     <ItemTemplate><%#Eval("Hobby") %></ItemTemplate> 
59                     <EditItemTemplate>
60                         <asp:CheckBoxList runat="server" ID="cbxlHobby" RepeatDirection="Horizontal" RepeatColumns="5">
61                         </asp:CheckBoxList>
62                     </EditItemTemplate>
63                 </asp:TemplateField>
64                 <asp:CommandField ShowDeleteButton="true" DeleteText="Delete" ShowEditButton="true" EditText="Edit" />
65             </Columns>
66             <PagerSettings Visible="true" />
67             <PagerStyle Font-Size="12px"/>
68             <PagerTemplate>
69                 <div style="float:left;margin-left:15px;color:#999;line-height:20px">
70                     当前第<%#this.gv.PageIndex+1 %>/<%#this.gv.PageCount %>页
71                 </div>
72                 <div style="float:right;margin-right:15px;color:#999;line-height:20px">页</div>
73                 <div style="float:right">
74                     <asp:DropDownList runat="server" ID="ddlPaging" AutoPostBack="true"
75                         OnSelectedIndexChanged="ddlPaging_OnSelectedIndexChanged">
76                     </asp:DropDownList>
77                 </div>
78                 <div style="float:right;color:#999;line-height:20px">跳转到第</div>
79             </PagerTemplate>
80         </asp:GridView>

说明:

1.因用了数据源控件,所以Name在编辑状态时使用<%#Bind("Name")%>来实现双向通讯的绑定

2.因为没有添加的功能,所以用了asp:CommandField来实现编辑、删除等按钮的功能。

3.排序功能上只要在ods上设定SortParameterName,它的值就是SelectMethod中关于排序的参数的名称,然后设定GridView的AllowSorting为true就ok了。排序按钮上依然用到GridView内置的CommandName——Sort,然后CommandArgument设为要排序的字段名,至于排序的方向由ObjectDataSource负责,省心多了。

.aspx.cs代码

  1 public partial class Default2 : System.Web.UI.Page
  2 {
  3     private OdsDataManager dm = new OdsDataManager();
  4 
  5     protected void Page_Load(object sender, EventArgs e)
  6     {
  7 
  8     }
  9 
 10     protected void gv_OnRowDataBound(object sender, GridViewRowEventArgs e)
 11     {
 12          DataRowView drv = e.Row.DataItem as DataRowView;
 13 
 14          if (e.Row.RowType == DataControlRowType.DataRow)
 15          {
 16              //显示时
 17              if (this.gv.EditIndex == -1)
 18              {
 19                  //设置性别
 20                  RadioButtonList rbl = e.Row.FindControl("rblSexShow") as RadioButtonList;
 21                  rbl.Items.Add(new ListItem("Male", "M"));
 22                  rbl.Items.Add(new ListItem("Female", "F"));
 23                  if ((drv["Sex"] as string).ToLower().Equals("m"))
 24                      rbl.Items[0].Selected = true;
 25                  else
 26                      rbl.Items[1].Selected = true;
 27              }
 28              //修改时:
 29              else if (e.Row.RowIndex == this.gv.EditIndex)
 30              {
 31                  //性别
 32                  RadioButtonList rbl = e.Row.FindControl("rblSexEdit") as RadioButtonList;
 33                  rbl.Items.Add(new ListItem("Male", "M"));
 34                  rbl.Items.Add(new ListItem("Female", "F"));
 35                  if ((drv["Sex"] as string).ToLower().Equals("m"))
 36                      rbl.Items[0].Selected = true;
 37                  else
 38                      rbl.Items[1].Selected = true;
 39                  //国籍
 40                  DropDownList ddlCountry = e.Row.FindControl("ddlCountry") as DropDownList;
 41                  DataTable countryDt = dm.GetCountry();
 42                  ListItem li = null;
 43                  for (int i = 0; i < countryDt.Rows.Count; ++i)
 44                  {
 45                      string cn = countryDt.Rows[i]["cn"] as string;
 46                      li = new ListItem(cn, cn);
 47                      if (cn.Equals(drv["Country"] as string))
 48                          li.Selected = true;
 49                      ddlCountry.Items.Add(li);
 50                  }
 51                  //兴趣
 52                  CheckBoxList cbl = e.Row.FindControl("cbxlHobby") as CheckBoxList;
 53                  DataTable hobbyDt = dm.GetHobby();
 54                  string hobbys = drv["Hobby"] as string;
 55                  ListItem hobbyLi = null;
 56                  string hstr = string.Empty;
 57                  for (int i = 0; i < hobbyDt.Rows.Count; i++)
 58                  {
 59                      hstr = hobbyDt.Rows[i]["hobby"] as string;
 60                      hobbyLi = new ListItem(hstr, hstr);
 61                      if (hobbys.IndexOf(hstr) >= 0)
 62                          hobbyLi.Selected = true;
 63                      cbl.Items.Add(hobbyLi);
 64                  }
 65              }
 66          }
 67          else if (e.Row.RowType == DataControlRowType.Pager)
 68          {
 69              //绑定分页控件
 70              DropDownList ddlPaging = e.Row.FindControl("ddlPaging") as DropDownList;
 71              for (int i = 0; i < this.gv.PageCount; i++)
 72              {
 73                  ddlPaging.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i)));
 74              }
 75              ddlPaging.SelectedIndex = this.gv.PageIndex;
 76          }
 77     }
 78 
 79     /// <summary>
 80 /// 分页控件的OnSelectedIndexChanged
 81 /// </summary>
 82 /// <param name="sender"></param>
 83 /// <param name="e"></param>
 84     protected void ddlPaging_OnSelectedIndexChanged(object sender, EventArgs e)
 85     {
 86         this.gv.PageIndex = (sender as DropDownList).SelectedIndex;
 87     }
 88 
 89     protected void ods_OnUpdating(object sender, ObjectDataSourceMethodEventArgs e)
 90     {
 91         string Sex = (this.gv.Rows[this.gv.EditIndex].FindControl("rblSexEdit") as RadioButtonList).SelectedValue;
 92         string Country = (this.gv.Rows[this.gv.EditIndex].FindControl("ddlCountry") as DropDownList).SelectedValue;
 93         System.Text.StringBuilder hobbys = new System.Text.StringBuilder();
 94         foreach (ListItem li in (this.gv.Rows[this.gv.EditIndex].FindControl("cbxlHobby") as CheckBoxList).Items)
 95         {
 96             if (li.Selected)
 97                 hobbys.Append(li.Value+",");
 98         }
 99         if (hobbys.Length >= 2)
100             hobbys.Remove(hobbys.Length - 1, 1);
101 
102         e.InputParameters.Add("Sex", Sex);
103         e.InputParameters.Add("Country", Country);
104         e.InputParameters.Add("Hobby",hobbys.ToString());
105     }
106 }

说明:

1.看到behind code是不是发现代码量少了很多呢?这就是用ods的好处了。

2.在更新操作时,因为Country、Sex和Hobby都没有和ods作双向绑定,所以要自己获取并写入到ods的InputParameters中,然后ods就会调用已经设置好的UpdateMethod了。

数据操作类

  1 public class OdsDataManager
  2 {
  3     private static DataTable dt = null;//用户记录
  4     private static DataTable countryDt = null;//国籍
  5     private static DataTable hobbyDt = null;//兴趣
  6 
  7     public OdsDataManager()
  8     {
  9         if (dt == null)
 10         {
 11             dt = new DataTable();
 12             dt.Columns.Add("ID");
 13             dt.Columns.Add("Name");
 14             dt.Columns.Add("Sex");
 15             dt.Columns.Add("Country");
 16             dt.Columns.Add("Hobby");
 17 
 18             //Default Data
 19             dt.Rows.Add(new object[] { 1, "Mary", "F", "China", "Cooking,Music" });
 20             dt.Rows.Add(new object[] { 2, "John", "M", "China", "Tennis" });
 21         }
 22 
 23         if (countryDt == null)
 24         {
 25             countryDt = new DataTable();
 26             countryDt.Columns.Add("cn");
 27 
 28             //Default Data
 29             countryDt.Rows.Add(new object[] { "China" });
 30             countryDt.Rows.Add(new object[] { "French" });
 31             countryDt.Rows.Add(new object[] { "America" });
 32             countryDt.Rows.Add(new object[] { "Afria" });
 33             countryDt.Rows.Add(new object[] { "Japan" });
 34         }
 35 
 36         if (hobbyDt == null)
 37         {
 38             hobbyDt = new DataTable();
 39             hobbyDt.Columns.Add("hobby");
 40 
 41             //Default Data
 42             hobbyDt.Rows.Add(new object[] { "Cooking" });
 43             hobbyDt.Rows.Add(new object[] { "Music" });
 44             hobbyDt.Rows.Add(new object[] { "Reading" });
 45             hobbyDt.Rows.Add(new object[] { "Movies" });
 46             hobbyDt.Rows.Add(new object[] { "Tennis" });
 47         }
 48     }
 49 
 50     public DataTable GetRecord(int maximumRows, int startRowIndex, string sortExpression)
 51     {
 52         //排序
 53         if(!string.IsNullOrEmpty(sortExpression))
 54         {
 55             dt.DefaultView.Sort = sortExpression;
 56         }
 57 
 58         DataRow[] drs = dt.Select();
 59         DataTable dt1 = dt.Clone();
 60         for (int i = startRowIndex; i < startRowIndex+maximumRows && i<drs.Length; i++)
 61         {
 62             dt1.Rows.Add(drs[i].ItemArray);
 63         }
 64 
 65         return dt1;
 66     }
 67 
 68     public int GetRecordCount()
 69     {
 70         return dt.Rows.Count;
 71     }
 72 
 73     public bool UpdateRecord(int ID, string Name, string Sex, string Country, string Hobby)
 74     {
 75         bool result = false;
 76         DataRow[] drs = dt.Select("ID=" + ID);
 77         if (drs.Length == 1)
 78         {
 79             drs[0]["Name"] = Name;
 80             drs[0]["Sex"] = Sex;
 81             drs[0]["Country"] = Country;
 82             drs[0]["Hobby"] = Hobby;
 83 
 84             result = true;
 85         }
 86 
 87         return result;
 88     }
 89 
 90     public bool DelRecord(int ID)
 91     {
 92         bool result = false;
 93         DataRow[] drs = dt.Select("ID=" + ID);
 94         if (drs.Length == 1)
 95         {
 96             dt.Rows.Remove(drs[0]);
 97 
 98             result = true;
 99         }
100 
101         return result;
102     }
103 
104     public DataTable GetCountry()
105     {
106         return countryDt;
107     }
108 
109     public DataTable GetHobby()
110     {
111         return hobbyDt;
112     }
113 }

说明:

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附带的缓存功能。具体请看:http://www.cnblogs.com/fsjohnhuang/archive/2011/12/19/2292947.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏汪毅雄的专栏

Android 7.0 中 ContentProvider 实现原理

本文描述了 ContentProvider 发布者和调用者这两在 Framework 层是如何实现的。

7662
来自专栏hbbliyong

WCF发布多个服务

using System; using System.Collections.Generic; using System.Linq; using System....

3735
来自专栏个人随笔

体检套餐管理系统 -- Dictionary<K,V>双列集合

本文章为 Dictionary<K,V>双列集合开发项目,如需要List<T>单列集合开发的此项目,请到楼主博客园寻找 博客网址:http://www.cnbl...

2885
来自专栏跟着阿笨一起玩NET

关于asp.net与winform导出excel的代码

一、asp.net中导出Execl的方法: 在asp.net中导出Execl有两种方法,一种是将导出的文件存放在服务器某个文件夹下面,然后将文件地址输出在...

1001
来自专栏菩提树下的杨过

ModalPopupExtender用法示例

aspx页面 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs...

2098
来自专栏ASP.NET MVC5 后台权限管理系统

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(11)-系统日志和异常的处理①

系统需要越来越自动化,我们需要引入日志记录和异常捕获 管理员的操作记录需要被记录,看出哪些模块是频繁操作,分析哪些是不必要的功能,哪些是需要被优化的。 系统的异...

3048
来自专栏跟着阿笨一起玩NET

c# 使用timer定时器操作,上次定时到了以后,下次还未执行完怎么处理

------解决方案-------------------------------------------------------- 开始的时候,禁用定时器,你...

6011
来自专栏飞扬的花生

C#实现Excel模板导出和从Excel导入数据

      午休时间写了一个Demo关于Excel导入导出的简单练习 1.窗体 ? 2.引用office命名空间 添加引用-程序集-扩展-Microsoft.O...

6477
来自专栏salesforce零基础学习

salesforce 零基础学习(三十三)通过REST方式访问外部数据以及JAVA通过rest方式访问salesforce

本篇参考Trail教程: https://developer.salesforce.com/trailhead/force_com_dev_intermedia...

5798
来自专栏腾讯Bugly的专栏

Android 7.0中ContentProvider实现原理

| 导语 本文描述了ContentProvider发布者和调用者这两在Framework层是如何实现的。 作为Android的四大组件之一,ContentPro...

4416

扫码关注云+社区

领取腾讯云代金券