用过JSF的,相信值绑定表达式不会太陌生。值绑定表达式就是像#{somebean.somevariable}这样简单的东东,JSF处理这样的表达式然后创建数据以便在JSF生命周期的后续阶段使用。
使用表达式,对于.NET来说,简化了一些数据表的制作,对于复杂的表格尤其有显著效果。
一、代码介绍:
/**/
/*----------------------------------------------------------------
// 文件名: table.cs
//
// 目前已经支持域绑定#{字段名}如公司名:#{productname},序列绑定#{@seq} 如sy_#{@seq}则为sy_0,sy_1,sy_2……,
// param绑定#{@param:}如#{@param:autoid}则为地址栏传过来的autoid,自定义值#{@custom:} 如#{@custom:myval},
// 多表值域#{表名.字段名} 如#{userinfo.userid},排序列绑定@{字段名}如class="@{companyname} 表示公司名列要应用样式绑定式排序",
// 枚举绑定 如新旧程度:#{oldlevel!0:全新,1:九成新,2:八成新,3:七成新,4:五成新} 如oldlevel字段为3则显示7成新 等格式
//
//
//
// 不会飞的鱼
//----------------------------------------------------------------*/
using
System;
using
System.Web;
using
System.Web.UI;
using
System.Collections;
using
System.Data;
using
vista.Util.Data;

namespace
ViewLogic.UI

...
{

public class table : Control

...{
private IDataSource _dataSource = null;
private IList _columnList = null;
private string _sortDirect = null;
private string _colname = null;
private System.Collections.Specialized.NameValueCollection _params = null;
private IDictionary _customvalue = null;

public IDataSource DataSource

...{
get

...{
return _dataSource;
}
set

...{
_dataSource = value;
}
}

public System.Collections.Specialized.NameValueCollection Params

...{

get...{return _params;}

set...{_params = value;}
}

public IDictionary CustomValue

...{

get...{return _customvalue;}

set...{_customvalue = value;}
}

public IList ColumnList

...{
get

...{
if(DataSource==null)
return null;
string htmlSource = ((LiteralControl) Controls[0]).Text;
System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(htmlSource,@"#{[@w]+}");
_columnList = new ArrayList(mc.Count);

foreach(System.Text.RegularExpressions.Match m in mc)

...{
string colName = System.Text.RegularExpressions.Regex.Replace(m.Groups[0].Value,@"[#{}]","");
if(colName.IndexOf("@")!=0)

...{
_columnList.Add(colName);
}
}
return _columnList;
}
}

public string ColName

...{

set ...{ _colname = value;}
}


public string SortDriect

...{
set

...{
_sortDirect = value;
}
}

protected override void Render(HtmlTextWriter output)

...{

if ( (HasControls()) && (Controls[0] is LiteralControl) && _dataSource!=null)

...{
string htmlSource = ((LiteralControl) Controls[0]).Text;
bool flag = true;
int i=0;
if(_sortDirect!=null)

...{
htmlSource = htmlSource.Replace("@{"+ _colname +"}","sortOrder"+_sortDirect);
}

while(_dataSource.MoveNext())

...{
DataRow dr = _dataSource.Current as DataRow;
i ++;
System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(htmlSource,@"#{[@!.,:w]+}");
string outstr = htmlSource;

foreach(System.Text.RegularExpressions.Match m in mc)

...{

string colName = System.Text.RegularExpressions.Regex.Replace(m.Groups[0].Value,@"[#{}]","");
if(colName.IndexOf("@")==0)

...{
if(colName.Trim().Equals("@seq"))
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,i.ToString());
else if(colName.Trim().IndexOf("@param:") == 0)

...{
string[] pars = colName.Split(':');
string realparam = pars[1];

outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,Params[realparam].ToString());
}
else if(colName.Trim().IndexOf("@custom:") == 0)

...{
string[] customs = colName.Split(':');
string realcustom = customs[1];
if(CustomValue[realcustom] is string)
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,CustomValue[realcustom].ToString());
else if(CustomValue[realcustom] is IList)

...{
string temp = (CustomValue[realcustom] as IList)[i-1].ToString();
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,temp);
}

}
}
else if(colName.IndexOf(".")!=-1)

...{
string[] colNameSplit = colName.Split('.');
DataTable dt = dr.Table.DataSet.Tables[colNameSplit[0]];
foreach(DataRow dr2 in dt.Rows)

...{
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,dr2[colNameSplit[1]].ToString());
}
}
else

...{
if(colName.IndexOf("!")!=-1)

...{
string[] exps = colName.Split('!');
string explist = exps[1];
string[] expitems = explist.Split(',');
bool fFound = false;
foreach(string expitem in expitems)

...{
string[] hashitem = expitem.Split(':');

if(hashitem[0]==dr[exps[0]].ToString())

...{
string realoutput = hashitem[1];
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,realoutput);
flag = true;
break;
}
}
if(!fFound)

...{
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,"");
}
}
else

...{
outstr = System.Text.RegularExpressions.Regex.Replace(outstr,m.Groups[0].Value,dr[colName].ToString());
}
}

}
output.Write(outstr);
flag = false;
}
}
}


}
}

IDataSource接口,为table.cs提供数据源:
using
System;
using
System.Collections;

namespace
ViewLogic.Data

...
{

/**//// <summary>
/// IDataSource是一个通用的数据接口,有一个方法GetDataField
/// </summary>
public interface IDataSource : IEnumerator

...{

/**//// <summary>
/// GetDataField方法,取得指定名称域的值
/// </summary>
/// <param name="name">域的名称</param>
/// <returns></returns>
string GetDataField(string name);
}
}
工厂类,具体数据来源的创建,想要什么就制作什么,比如下面的DataSet,DataTable或者更多:
using
System;
using
System.Data;

namespace
ViewLogic.Data

...
{

/**//// <summary>
/// DataSourceFactory为工厂类,返回IDataSource接口类型
/// </summary>
public class DataSourceFactory

...{
public DataSourceFactory()

...{
}


/**//// <summary>
///
/// </summary>
/// <param name="ds">DataSet</param>
/// <returns></returns>
public static IDataSource Create(DataSet ds)

...{
return Create(ds.Tables[0]);
}


/**//// <summary>
///
/// </summary>
/// <param name="dt">DataTable</param>
/// <returns></returns>
public static IDataSource Create(DataTable dt)

...{
return new DataList(dt);
}
}
}
基类:
using
System;
using
System.Collections;
using
System.Reflection;

namespace
ViewLogic.Data

...
{

/**//// <summary>
/// DataBase 的摘要说明。
/// </summary>
public abstract class DataBase : IDataSource

...{
public DataBase()

...{
}


/**//// <summary>
///
/// </summary>
private IEnumerator enumerator;


/**//// <summary>
///
/// </summary>
protected IEnumerator Enumerator

...{
get

...{
return enumerator;
}
set

...{
enumerator = value;
}
}


IDataSource 成员#region IDataSource 成员


/**//// <summary>
/// GetDataField
/// </summary>
/// <param name="name">string</param>
/// <returns></returns>
public abstract string GetDataField(string name);

#endregion


IEnumerator 成员#region IEnumerator 成员


/**//// <summary>
///
/// </summary>
public void Reset()

...{
enumerator.Reset();
}


/**//// <summary>
///
/// </summary>
public object Current

...{
get

...{
return enumerator.Current;
}
}


/**//// <summary>
///
/// </summary>
/// <returns></returns>
public bool MoveNext()

...{
return enumerator.MoveNext();
}

#endregion
}
}
具体的操作:
using
System;
using
System.Data;

namespace
ViewLogic.Data

...
{

/**//// <summary>
/// DataList 的摘要说明。
/// </summary>
public class DataList : DataBase

...{
protected DataList()

...{
}


/**//// <summary>
/// DataList
/// </summary>
/// <param name="table">DataTable</param>
public DataList(DataTable table)

...{
this.Enumerator = table.Rows.GetEnumerator();
}


/**//// <summary>
/// GetDataField
/// </summary>
/// <param name="name">string</param>
/// <returns>string</returns>
public override string GetDataField(string name)

...{
if(Enumerator.Current != null)

...{
DataRow row = Enumerator.Current as DataRow;
if(row != null)

...{
return row[name].ToString();
}
else

...{
return null;
}
}
else

...{
return null;
}
}
}

}
二、使用:
1、准备工作:因为是自定义控件,所以要引用进来<%@ Register TagPrefix="tbl" Namespace="ViewLogic.UI" Assembly="ViewLogic"%>
2、简单前台绑定:
<
table
>
<
tr
>
<
td
>
姓名
</
td
>
<
td
>
年龄
</
td
>
</
tr
>
<tbl:table id="tbl1" runat="server">
<
tr
>
<
td
>
#{username}
</
td
>
<
td
>
#{age}
</
td
>
</
tr
>
</tbl:table>
</
table
>
对应后台绑定:
声明:protected ViewLogic.UI.table tbl1;
绑定:tbl1.DataSource = DataSourceFactory.Create(dt); // dt 为 一个DataTable的实例
tbl1.DataBind();
OK,可以使用了。当然,你的dt 里面要包含username和age这两个列
3、序列绑定:
排名 姓名
1 wang
2 zhang
3 li
而 1、2、3是图片img_1.gif,img_2.gif,img_3.gif
则
<
table
>
<
tr
>
<
td
>排
名
</
td
>
<
td
>
姓名
</
td
>
</
tr
>
<tbl:table id="tbl1" runat="server">
<
tr
>
<
td
><img src="img"</td
_#{@seq}.gif
>
<
td
>
#{age}
</
td
>
</
tr
>
</tbl:table>
</
table
>
后台绑定同2的后台
4、多表绑定:同2,只是#{表名.列名}的形式,并且,绑定的DataSet里的Table[0]可以省去表明直接写
#{列名},而DataSet里的Tables[1]绑定列则必须写Table[1]的名字,比如#{tb1.age}
5、传值绑定:
包括地址栏和自定义两种:
1) 地址栏传值:
前台: 如a.aspx?id=1 页面里有 <a href="test.aspx?id=#{@param:id}">查看详细</a>
则 <a href="test.aspx?id=1">查看详细</a>
后台: tbl1.Params = Request.Params;
2) 自定义传值:
前台:假设<a href="test.aspx?id=#{@custom:bookid}&year=#{@custom:year}">查看书目</a>
后台: Hashtable ht = new Hashtable();
ht.add("bookid","1");
ht.add("year","2006");
也可以进行一键多值绑定:
Hashtable ht = new Hashtable();
ht.add("bookid","1");
ArrayList ar = new ArrayList();
ar.Add("2006");
ar.Add("2007");
………………
ht.add("year",ar);
6、枚举绑定:
前台:<TD>新旧程度:#{oldlevel!0:全新,1:九成新,2:八成新,3:七成新,4:五成新}</TD>
后台:同2绑定。
如果列oldlevel 值为 3 则显示 七成新
7、排序绑定:
结合我的《样式绑定驱动脚本……》一文,进行前台的排序样式绑定。
好了完成了,还是那句话,DEMO,DEMO而已,为的是发散思维,拓宽思路,当然大家完全可以自己制作这些代码,关键是思想,用.NET进行快速开发确实还有很长的路要走,asp.net的硬框架也不如J2EE的众多框架那样灵活,所以还要有天才的大家们共同研究………………