教你30秒打造強類型ASP.NET數據綁定

作者: dragonpig  來源: 博客園  發布時間: 2011-01-31 13:11  閱讀: 1811 次  推薦: 2   原文鏈接   [收藏]  

  相關文章:強類型ASP.NET數據綁定改進版強類型ASP.NET數據綁定改進版之第2版

  數據綁定似乎是ASP.NET老掉牙的東西了。可是你知道嗎,只需要一點小小的改動就可以替換Eval,擺脫字符串依賴并且大大提高性能。

  首先在code behind中加入以下方:

 
protected virtual object ExpHelper<TEntity, TREsult>(Func<TEntity, TREsult> func)
{
var itm
= GetDataItem();
return func((TEntity)itm);
}

  這段代碼就是最核心的秘訣了,你完全可以忽視它到底在做什么。其實就是截獲每一個被綁定的數據項,并進行強類型轉換。

  假設我們定義了學生類:  

 
public class Student
{

public string Name { get; set; }
public int Age { get; set; }
}

  如果希望在頁面中使用強類型訪問學生類而不是用Eval,定義專門訪問學生的方法:

 
protected object Stu<TResult>(Func<Student, TResult> func)
{

return ExpHelper<Student, TResult>(func);
}

  大功告成,于是在頁面里我們就能這樣綁定數據了:

 
<ul>
<asp:Repeater ID="rptStudents" runat="server">
<ItemTemplate>
<li><%#Stu(_=>_.Name + "(" +_.Age+")")%></li>
</ItemTemplate>
</asp:Repeater>
</ul>

  這樣做有四大優勢:

  1. 得到編譯時檢測
  2. 享受智能提示
  3. 強類型轉換比Eval反射性能更高
  4. 頁面中的表示更豐富,如上我們可以自由拼接想要的字符串,非常像MVC

  更神奇的是可以支持多層嵌套哦。比如我們定義學生的集合Group類和訪問器,然后就能用嵌套的Repeater顯示分組信息了。完整程序如下:

 
<%@ Page Language="C#" AutoEventWireup="true"%>
<script runat="server">
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}

public class Group
{
public IEnumerable
<Student> Students { get; set; }
}

protected void Page_Load(object sender, EventArgs e)
{
//一群學生
var students = new[] {
new Student{Name="mike",Age=23},
new Student{Name="jane", Age=12},
new Student{Name="frank",Age=25},
new Student{Name="susan",Age=32},
};

rptStudents.DataSource = students;

//分兩組
var group0 = new Group();
group0.Students = students.Take(2);

var group1 = new Group();
group1.Students = students.Skip(2).Take(2);

rptGroups.DataSource = new[] { group0, group1 };
DataBind();
}

protected virtual object ExpHelper
<TEntity, TREsult>(Func<TEntity, TREsult> func)
{
var itm = GetDataItem();
return func((TEntity)itm);
}

//Student訪問器
protected object Stu
<TResult>(Func<Student, TResult> func)
{
return ExpHelper
<Student, TResult>(func);
}
//Group訪問器
protected object Grp
<TResult>(Func<Group, TResult> func)
{
return ExpHelper
<Group, TResult>(func);
}

</script>

<!DOCTYPE html>
<html>
<body>
<%--單層--%>
<ul>
<asp:Repeater ID="rptStudents" runat="server">
<ItemTemplate>
<li><%#Stu(_=>_.Name + "(" +_.Age+")")%></li>
</ItemTemplate>
</asp:Repeater>
</ul>

<%--嵌套--%>
<ul>
<asp:Repeater ID="rptGroups" runat="server">
<ItemTemplate>
<li>
<ol>
<asp:Repeater ID="Repeater1" runat="server" DataSource='<%#Grp(_=>_.Students) %>'>
<ItemTemplate>
<li><%#Stu(_=>_.Name + "(" +_.Age+")")%></li>
</ItemTemplate>
</asp:Repeater>
</ol>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</body>
</html>

  PS:本文是我以前寫的沒有發表的小發明,現在拿出來曬,主要是因為這個方法好像知道的人很少。希望大家能幫助測試一下性能,如果覺得合適大可以運用到實際工作中。

  更新:

  感謝Dacey 韋恩卑鄙 dudu老大等人的建議。
  我已添加了擴展方法版本。喜歡擴展方法這種空降兵的感覺。

  現在只要添加一個static的幫助類,名字隨你喜歡:

 
public static class Helper
{

static object ExpHelper<TEntity, TResult>(Page page, Func<TEntity, TResult> func)
{
var itm
= page.GetDataItem();
return func((TEntity)itm);
}


public static object Eval<T>(this Page page, Func<T, object> func)
{

return ExpHelper<T, object>(page, func);
}
}

  在頁面中就可以:

 
<%#this.Eval<Student>(_ => _.Name + "(" + _.Age + ")")%>
  • 注意this是必須的。
  • 擴展方法具有很好的粘合性。
  • 不需要一個父類定義通用方法。
  • 泛型提供多個副本并且容易看清類型。
  • 另外能很好的支持refactor,大家試試用ctrl+r+r改屬性名。
2
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()