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.Page2 {
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 OdsDataManager2 {
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
?
轉載于:https://www.cnblogs.com/fsjohnhuang/archive/2011/12/17/2291118.html
總結
以上是生活随笔為你收集整理的GridView实战二:使用ObjectDataSource数据源控件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7个你不知道的WP7开发工具
- 下一篇: 【转】使 用免费UMS架设Flash流媒