• 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



    欢迎添加我的公众号一起深入探讨技术手艺人的那些事!

    如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!
      

  • 相关阅读:
    作业1
    113
    112
    工作量统计
    测试大纲
    2019-2020-2 20175335丹增罗布《网络对抗技术》Exp8 Web基础
    2019-2020-2 20175335丹增罗布 《网络对抗技术》Exp7 网络欺诈防范
    2019-2020-2 20175335丹增罗布 《网络对抗技术》Exp6 MSF基础应用
    2019-2020-2 20175335 丹增罗布 《网络对抗技术》Exp5 信息搜集与漏洞扫描
    2019-2020-2 20175335 丹增罗布《网络对抗技术》Exp4 恶意代码分析
  • 原文地址:https://www.cnblogs.com/fsjohnhuang/p/2291118.html
Copyright © 2020-2023  润新知