有一个菜单树,因为界面上的限制(要求)不能使用现有的控件。
那我就想到了用Repeater控件自己来写,可以灵活、方便的控制页面。
<
asp:Repeater
ID
="CategoryList"
runat
="server"
OnItemDataBound
="CategoryList_ItemDataBound"
>
< HeaderTemplate >
< div style ="width: 90%; text-align:left; padding-left:10px;" >
</ HeaderTemplate >
< ItemTemplate >
< div style ="line-height:30px;" >
< img src ="images/jt_red.gif" width ="3" height ="5" />< img src ="images/jt_red.gif"
width ="3" height ="5" />
< asp:HyperLink ID ="hlRootCategory" CssClass ="dh" runat ="server" > Category </ asp:HyperLink >
</ div >
</ ItemTemplate >
< FooterTemplate >
</ div >
</ FooterTemplate >
</ asp:Repeater >
< HeaderTemplate >
< div style ="width: 90%; text-align:left; padding-left:10px;" >
</ HeaderTemplate >
< ItemTemplate >
< div style ="line-height:30px;" >
< img src ="images/jt_red.gif" width ="3" height ="5" />< img src ="images/jt_red.gif"
width ="3" height ="5" />
< asp:HyperLink ID ="hlRootCategory" CssClass ="dh" runat ="server" > Category </ asp:HyperLink >
</ div >
</ ItemTemplate >
< FooterTemplate >
</ div >
</ FooterTemplate >
</ asp:Repeater >
这里没有使用数据源控件。而是在后台动态绑定的数据。
protected
void
Page_Load(
object
sender, EventArgs e)
{
DataSet ds = new Aricc.ooxx.BLL.Category().GetList( " parentid=0 " );
CategoryList.DataSource = ds;
CategoryList.DataBind();
}
protected void CategoryList_ItemDataBound( object sender, RepeaterItemEventArgs e)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
HyperLink link = (HyperLink)e.Item.FindControl( " hlRootCategory " );
if (link != null )
{
link.Text = drv[ " categoryname " ].ToString();
link.NavigateUrl = " ../search.aspx?c= " + drv[ " id " ].ToString();
ListInnerCategory(e.Item, int .Parse(drv[ " id " ].ToString()));
}
}
{
DataSet ds = new Aricc.ooxx.BLL.Category().GetList( " parentid=0 " );
CategoryList.DataSource = ds;
CategoryList.DataBind();
}
protected void CategoryList_ItemDataBound( object sender, RepeaterItemEventArgs e)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
HyperLink link = (HyperLink)e.Item.FindControl( " hlRootCategory " );
if (link != null )
{
link.Text = drv[ " categoryname " ].ToString();
link.NavigateUrl = " ../search.aspx?c= " + drv[ " id " ].ToString();
ListInnerCategory(e.Item, int .Parse(drv[ " id " ].ToString()));
}
}
看到那个ListInnerCategory方法了吗?它就是递归显示子类数据方法。在这个方法里会动态的创建Repeater控件,并绑定相应的数据。
要动态创建Repeater控件,必须要定义Template。用于对Repeater的ItemTemplate进行赋值。而这个Template需要是实现了ITemplate接口的一个类的实例。
那么下面我们首先定义这样的一个模板类
public
class
CategoryTemplate : ITemplate
{
#region ITemplate 成员
private int currentLevel;
public CategoryTemplate( int level)
{
currentLevel = level;
}
public void InstantiateIn(Control container)
{
HyperLink link = new HyperLink();
link.ID = " innerLink " ;
HtmlGenericControl div = new HtmlGenericControl();
div.TagName = " div " ;
div.Attributes.Add( " style " , " line-height:30px;text-indent: " + (currentLevel * 20 ) + " px; " );
div.ID = " innerDiv " ;
div.Controls.Add(link);
container.Controls.Add(div);
}
#endregion
}
{
#region ITemplate 成员
private int currentLevel;
public CategoryTemplate( int level)
{
currentLevel = level;
}
public void InstantiateIn(Control container)
{
HyperLink link = new HyperLink();
link.ID = " innerLink " ;
HtmlGenericControl div = new HtmlGenericControl();
div.TagName = " div " ;
div.Attributes.Add( " style " , " line-height:30px;text-indent: " + (currentLevel * 20 ) + " px; " );
div.ID = " innerDiv " ;
div.Controls.Add(link);
container.Controls.Add(div);
}
#endregion
}
接下来是ListInnerCategory的定义及相应的事件处理程序
private
int
currentLevel
=
0
;
private void ListInnerCategory(RepeaterItem item, int ID)
{
if ( new Aricc.ooxx.BLL.Category().HasChild(ID))
{
currentLevel ++ ;
DataSet ds = new Aricc.ooxx.BLL.Category().GetList( " parentid= " + ID);
Repeater rep = new Repeater();
CategoryTemplate template = new CategoryTemplate(currentLevel);
rep.ItemTemplate = template;
rep.ItemDataBound += new RepeaterItemEventHandler(rep_ItemDataBound);
rep.DataSource = ds;
rep.DataBind();
item.Controls.Add(rep);
currentLevel -- ;
}
}
void rep_ItemDataBound( object sender, RepeaterItemEventArgs e)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
HyperLink link = (HyperLink)e.Item.FindControl( " innerLink " );
if (link != null )
{
link.Text = drv[ " categoryname " ].ToString();
link.NavigateUrl = " ../search.aspx?c= " + drv[ " id " ].ToString();
ListInnerCategory(e.Item, int .Parse(drv[ " id " ].ToString()));
}
}
private void ListInnerCategory(RepeaterItem item, int ID)
{
if ( new Aricc.ooxx.BLL.Category().HasChild(ID))
{
currentLevel ++ ;
DataSet ds = new Aricc.ooxx.BLL.Category().GetList( " parentid= " + ID);
Repeater rep = new Repeater();
CategoryTemplate template = new CategoryTemplate(currentLevel);
rep.ItemTemplate = template;
rep.ItemDataBound += new RepeaterItemEventHandler(rep_ItemDataBound);
rep.DataSource = ds;
rep.DataBind();
item.Controls.Add(rep);
currentLevel -- ;
}
}
void rep_ItemDataBound( object sender, RepeaterItemEventArgs e)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
HyperLink link = (HyperLink)e.Item.FindControl( " innerLink " );
if (link != null )
{
link.Text = drv[ " categoryname " ].ToString();
link.NavigateUrl = " ../search.aspx?c= " + drv[ " id " ].ToString();
ListInnerCategory(e.Item, int .Parse(drv[ " id " ].ToString()));
}
}
到此,一个多级的树菜单就出来了。
也许我这里的应用不是一个好的解决方案。
我写这篇文章的目的主要是说明Repeater的动态创建问题。就像题目中说的。
希望对你有所帮助。