但是當你的Gridview顯示出來的欄位並非一次就能用一個SQL完全抓出來,必須在RowDataBound再處理過、甚至再次下SQL抓取時,就無法使用內建的排序功能了,因為當它使用第一次BindData時的SQL去做order by時,會因為找不到那個另外處理的欄位而報錯,這時只能自已來處理排序功能了。
其實手動自已做的排序功能的流程大致都跟使用內建的流程一樣,也是先開啟GridView的AllowSorting以及GridView_Sorting()函式,差別就在於要在GridView_Sorting()函式中自已把現在GridView的所有資料暫存下來,做好排序後再重新BindDate給GridView。而在此要示範的是用List<obj>來暫存資料,因為它有內建的linq排序函式OrderByDescending()跟OrderBy()。
首先可以在Page_Load()加個ViewState記錄排序的升冪或降冪:
protected void Page_Load(object sender, EventArgs e) { ... if (!IsPostBack) ViewState["sort"] = "asc"; ... }
再來是GridView_Sorting()的寫法:
protected void GridView_Sorting(object sender, GridViewSortEventArgs e) { //暫存現有GridView的資料 List<obj> lts = GetCurrentGridView(); //判斷先前是升冪或降冪, 這次就要相反排 if (ViewState["sort"].ToString() == "asc") { lts = lts.OrderByDescending(p => GetPropertyValue(p, e.SortExpression)).ToList(); ViewState["sort"] = "desc"; } else { lts = lts.OrderBy(p => GetPropertyValue(p, e.SortExpression)).ToList(); ViewState["sort"] = "asc"; } //重新BindDate BindView(lts); } //使用反射,根據屬性的型別找出屬性的內容值 public static object GetPropertyValue(object obj, string property) { System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(property); return propertyInfo.GetValue(obj, null); } private List<obj> GetCurrentGridView() { List<obj> list = new List<obj>(); for (int i = 0; i < gv.Rows.Count; i++) { obj o = new obj(); o.lbl1 = ((Label)gv.Rows[i].FindControl("lbl1")).Text; o.lbl2 = ((Label)gv.Rows[i].FindControl("lbl2")).Text; o.lbl3 = ((Label)gv.Rows[i].FindControl("lbl3")).Text; list.Add(o); } return list; } private void BindView(List<obj> list) { gv.DataSource = list; gv.DataBind(); }
沒有留言:
張貼留言