Treeview绑定数据源 层叠结构数据源的应用
Treeview绑定数据源 层叠结构数据源的应用
以前使用Treeview服务端控件来展示目录树或者权限树的时候,都是直接使用遍历来填充节点的,这样做很大的劣势就是每使用一次就需要重新写一次遍历的代码,复用性非常的低。并且从性能上考虑的话,估计也没有直接使用绑定数据源的高(自己估计没有实际测试)
这几天正好又要使用一个TreeView来做一个栏目导航,我就尝试了一下使用层叠结构数据源来绑定数据。现在我们一起来研究一下整个绑定过程,绑定结束后,有个小问题,还要和大家一起研究讨论下。
(可能已经有很多人尝试绑定xml之类的数据源了,今天我说的直接绑定的一个Datatable或者List<T>。在绑定过程中,我百度,我google了很多,但没有找到一个理想的答案,估计目前大家用这种绑定的比较少吧。比较接近的有一篇有参考价值的文章,大家可以参考下。点击打开)
以下是使用到的数据库的结构,其中没有使用到的字段我没有贴出来。
以下是自定义的层叠结构的代码,实现了某些接口,具体大家看代码。其中的ChannelInfo是我使用到的一个目录实体类,结构如上面的数据库结构。
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Entity;
using DataLogic;
/// <summary>
/// 层叠数据源的使用
/// 作者:房客
/// Blog:http://sxlfybb.cnblogs.com
/// </summary>
public class ChannelData: IHierarchyData
{
private List<ChannelInfo> _list = null;
private ChannelInfo _info = null;
public List<ChannelInfo> ChannelInfoList
{
set { _list = value; }
}
public ChannelInfo ChanInfo
{
set { _info = value; }
}
public ChannelData(ChannelInfo info,List<ChannelInfo> list)
{
_list = list;
_info = info;
}
public bool HasChildren
{
get {
foreach (ChannelInfo info in _list)
{
if (info.PID == _info.CID)
return true;
}
return false;
}
}
public string Path
{
get { return _info.ChannelUrl; }
}
public object Item
{
get
{
return _info;
}
}
public string Type
{
get { return _info.GetType().ToString(); }
}
public IHierarchyData GetParent()
{
foreach (ChannelInfo info in _list)
{
if (info.CID == _info.PID)
return info as IHierarchyData;
}
return null;
}
public IHierarchicalEnumerable GetChildren()
{
List<ChannelInfo> list = new List<ChannelInfo>();
if(_info.CID >0)
{
foreach (ChannelInfo info in _list)
{
if(info.PID == _info.CID)
{
list.Add(info);
}
}
}
return new HierarchicalCollection(list);
}
}
public class HierarchicalCollection:IHierarchicalEnumerable
{
private List<ChannelInfo> _list = null;
public List<ChannelInfo> ChannelInfoList
{
set { _list = value; }
}
public HierarchicalCollection(List<ChannelInfo> list)
{
_list = list;
}
public IHierarchyData GetHierarchyData(object enumeratedItem)
{
return new ChannelData(enumeratedItem as ChannelInfo, _list);
}
public System.Collections.IEnumerator GetEnumerator()
{
return _list.GetEnumerator();
}
}
以下是具体绑定的过程。
tv_Channel.DataSource = cdsv;
TreeNodeBinding bind = new TreeNodeBinding();
bind.TextField = "ChannelTitle";
bind.NavigateUrlField = "ChannelUrl";
bind.Target = "mainFrame";
bind.SelectAction = TreeNodeSelectAction.Expand;
tv_Channel.DataBindings.Add(bind);
tv_Channel.DataBind();
OK,代码结束,我们刷新一下页面,就会发现绑定成功了。
等等,发现了什么?是的,有一个小问题,就是我实现的这个类的后遗症。二三级栏目已经成功的附加到一级栏目下面,但是一级栏目把二三级栏目也显示出来了。这就是大问题了。但问题为什么会是这样呢?我尝试了一下,在实现接口IHierarchyData的ChannelData中,构造函数中,我把该对象应该对应的父编号也传进来,在Item属性中判断当前对象的父编号(PID)是否和传进来的编号一致,如不一致,返回为null。但这样好像也解决不了问题。
好了,大部分功能我也实现,后面的小问题,大家都一起研究一下,如果找到原因了,一定要记得回复,告诉我。谢谢