在项目中,有一个通讯录组以及通讯录的功能,通讯录组要求无限分级,树状结构显示 ,经过研究,完整地实现了树结构,效果如下
还可以实时添加,修改,删除,使用ajax实现,客户端不会刷新
下面先讲怎样在服务端实现这个树结构,首先,数据库设计至少三个字段,主建,名称,父节点(记录父节点主键),由于本项目中树结构较多,所以我用一个实体类来表示TreeEntity.cs
using
System;
using
System.Collections.Generic;
using
System.Text;

namespace
SmsSystem.Model

...
{
public class TreeEntity

...{

public TreeEntity() ...{ }


public TreeEntity(int id, string name, int parentId) ...{
this.id = id;
this.name = name;
this.parentId = parentId;
}
private int id;
private string name;
private int parentId;

public int Id

...{

get ...{ return id; }

set ...{ id = value ; }
}

public string Name

...{

get ...{ return name; }

set ...{ name = value ; }
}

public int ParentId

...{

get ...{ return parentId; }

set ...{ parentId = value; }
}

}
}
数据库访问层我在一篇文件中曾经提到过http://blog.csdn.net/cleverfoxloving/archive/2006/09/15/1226956.aspx具体实现不详述了,我用一个类返回一个IList<TreeEntity>(没接触过C#的泛型的这里可能不明白,请参阅相关资料)
/**/
/// <summary>
/// 获得数据列表返回ArrayList<TreeEntity>
/// </summary>
public
IList
<
TreeEntity
>
GetList(
int
companyRkey)

...
{
IList<TreeEntity> list = new List<TreeEntity>();
DataSet ds = this.GetDatasetList(" company_Rkey = " + companyRkey);

if (ds.Tables[0].Rows.Count > 0)

...{
foreach (DataRow dr in ds.Tables[0].Rows)

...{
TreeEntity tree = new TreeEntity();
tree.Id = int.Parse(dr["Rkey"].ToString());
tree.Name = dr["Groupname"].ToString();
tree.ParentId = int.Parse(dr["Parent_rkey"].ToString());

list.Add(tree);
}
}
return list;

}
接下来要写一个通用的方法,由list递归生成xml,GetTreeXML.cs
using
System;
using
System.Data;
using
System.Collections.Generic;
using
System.Xml;
using
System.IO;

using
SmsSystem.Model;

namespace
SmsSystem.Utility

...
{
public class GetTreeXML

...{

public GetTreeXML() ...{
}
public void addDataXml(XmlDocument xmlDoc, XmlElement xmlRootNode, IList<TreeEntity> list)

...{

foreach(TreeEntity treeEntity in list)...{
if (treeEntity.ParentId == int.Parse(xmlRootNode.GetAttribute("mid")))

...{
XmlElement xmlNewElemene = xmlDoc.CreateElement("subject");

xmlNewElemene.SetAttribute("mid", treeEntity.Id.ToString());
xmlNewElemene.SetAttribute("name", treeEntity.Name);
xmlNewElemene.SetAttribute("value", treeEntity.ParentId.ToString());
xmlRootNode.AppendChild(xmlNewElemene);
addDataXml(xmlDoc, xmlNewElemene, list);
}
}
}

public XmlDocument getGroupTree(IList<TreeEntity> list)

...{
XmlDocument xmlDoc = new XmlDocument();
XmlDeclaration objXmlDeclare = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
xmlDoc.InsertBefore(objXmlDeclare, xmlDoc.DocumentElement);
XmlElement xmlRootElem = xmlDoc.CreateElement("subject");
xmlRootElem.SetAttribute("mid", "0");
xmlRootElem.SetAttribute("name", "通讯录组群");
xmlDoc.AppendChild(xmlRootElem);
addDataXml(xmlDoc, xmlRootElem, list);
return xmlDoc;

}

public string getGruopTreeStr(IList<TreeEntity> list)

...{
return this.XmlDocumentToString(this.getGroupTree(list));
}

/**////………………(其它树结构)

public string XmlDocumentToString(XmlDocument doc)

...{
MemoryStream stream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(stream, null);
//writer.Formatting = Formatting.Indented;
doc.Save(writer);

StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
stream.Position = 0;
string xmlString = sr.ReadToEnd();
sr.Close();
stream.Close();

return xmlString;
}

}
}
这上面的四个方法是主要的核心方法,接下来就是客户端采用Ajax调用,以及有JS生成树结构显示了,只列出部分重要代码,首先简单说一个Ajax调用,采用AjaxPro.dll框架,具体用法参考相关资料,代码如下
protected
void
Page_Load(
object
sender, EventArgs e)

...
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(Address_AddressManage));
}
[AjaxPro.AjaxMethod]

public
string
GetAddressGruopStr()
...
{
if (null != Session["userInfo"])

...{
bool isAll = (((SmsSystem.BO.UserInfo)Session["userInfo"]).PopedomType == "1") ? true : false;
int userRkey = ((SmsSystem.BO.UserInfo)Session["userInfo"]).CustEmployee_Rkey;
SmsSystem.BLL.AddressGroup addressGroupBll = new SmsSystem.BLL.AddressGroup();
return addressGroupBll.getGroupTreeStr(userRkey, isAll);
}
else
