TreeView使用学习

前几天头说让我帮忙解决一个问题,写一个控件的绑定,其实就是一个的数据源绑定,的每个节点上要加CheckBox,当选中父节点时要选中子节点,但是只返回最底层节点的value和text。最后出来效果图如下:

无限部门分级选择员工TreeView

无限部门分级选择员工TreeView

递归实现的绑定。CS代码如下:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.stfTree.Attributes.Add(“onclick”, “return client_OnTreeNodeChecked();”);

TreeNode node = new TreeNode(“公司”, “0″);

LoadChildNode(node, test(), “parent_dept_id=0 “, “dept_id”, “dept_name”);

this.stfTree.Nodes.Add(node);
}
}

#region stffTree
private DataTable test()
{
DataTable rtn = new DataTable();

rtn.Columns.Add(“parent_dept_id”, typeof(String));
rtn.Columns.Add(“parent_dept_name”, typeof(String));
rtn.Columns.Add(“dept_id”, typeof(String));
rtn.Columns.Add(“dept_name”, typeof(String));
rtn.Columns.Add(“stn_id”, typeof(String));
rtn.Columns.Add(“stn_name”, typeof(String));
rtn.Columns.Add(“stf_id”, typeof(String));
rtn.Columns.Add(“stf_name”, typeof(String));

DataRow subRow = rtn.NewRow();
subRow["parent_dept_id"] = “0″;
subRow["parent_dept_name"] = “全部”;
subRow["dept_id"] = “01″;
subRow["dept_name"] = “部门1″;
subRow["stn_id"] = “001″;
subRow["stn_name"] = “岗位1″;
subRow["stf_id"] = “0001″;
subRow["stf_name"] = “员工1″;
rtn.Rows.Add(subRow);

DataRow subRow1 = rtn.NewRow();
subRow1["parent_dept_id"] = “0″;
subRow1["parent_dept_name"] = “全部”;
subRow1["dept_id"] = “02″;
subRow1["dept_name"] = “部门2″;
subRow1["stn_id"] = “002″;
subRow1["stn_name"] = “岗位2″;
subRow1["stf_id"] = “0002″;
subRow1["stf_name"] = “员工2″;
rtn.Rows.Add(subRow1);

DataRow subRow2 = rtn.NewRow();

subRow2["parent_dept_id"] = “01″;
subRow2["parent_dept_name"] = “全部”;
subRow2["dept_id"] = “03″;
subRow2["dept_name"] = “部门11″;
subRow2["stn_id"] = “003″;
subRow2["stn_name"] = “岗位3″;
subRow2["stf_id"] = “0003″;
subRow2["stf_name"] = “员工3″;
rtn.Rows.Add(subRow2);

DataRow subRow3 = rtn.NewRow();

subRow3["parent_dept_id"] = “01″;
subRow3["parent_dept_name"] = “全部”;
subRow3["dept_id"] = “03″;
subRow3["dept_name"] = “部门11″;
subRow3["stn_id"] = “003″;
subRow3["stn_name"] = “岗位3″;
subRow3["stf_id"] = “0004″;
subRow3["stf_name"] = “员工4″;
rtn.Rows.Add(subRow3);

DataRow[] dr = rtn.Select(“parent_dept_id=0″ );
dr = rtn.Select(“dept_id=01″);

return rtn;
}
/*
*  dt 四个字段 stf_id,stn_id,dept_id,parent_dept_id
*  先查询parent_dept_id添加到Hashtable key=parent_dept_id; value=parent_dept_name
*  遍历Hashtable,根据 parent_dept_id,查找dept_id添加到Hashtable key=dept_id; value=dept_name
*  遍历Hashtable,根据 dept_id,查找stn_id添加到Hashtable key=stn_id; value=stn_name
*  遍历Hashtable,根据 stn_id,查找stf_id添加到newNode
**/
/// <summary>
/// 递归填充treeView
/// </summary>
/// <param name=”node”>父节点</param>
/// <param name=”dt”>dt</param>
/// <param name=”condition”>查询条件 如parent_dept_id=”0″</param>
/// <param name=”key”>stf_id,stn_id,dept_id,parent_dept_id</param>
/// <param name=”value”>stf_id,stn_id,dept_id,parent_dept_id对应显示</param>
private int LoadChildNode(TreeNode node, DataTable dt, string condition, string key, string value)
{
IDictionary isFilled = new Hashtable();
//TODO:填充Hashtable
DataRow[] dr = dt.Select(condition);

for (int i = 0; i < dr.Length; i++)
{
string id = dr[i][key].ToString();
if (!isFilled.Contains(id))
{
string name = dr[i][value].ToString();
isFilled.Add(id, “”);
TreeNode subNode = new TreeNode(name, id);
string cond = condition.Split(‘=’)[0];
if (cond == “parent_dept_id”)
{
LoadChildNode(subNode, dt, “parent_dept_id=” + id + ” “, key, value) ;

LoadChildNode(subNode, dt, “dept_id=” + id + ” “, “stn_id”, “stn_name”);

}
else if (cond == “dept_id”)
{
LoadChildNode(subNode, dt, “stn_id=” + id + ” “, “stf_id”, “stf_name”);
}

node.ChildNodes.Add(subNode);
}
}

return dr.Length;
}

protected void on_click(object sender, EventArgs e)
{

}
#endregion
主要是JS上比较复杂,要研究过TreeView生成完的HTML代码,里面DIV和Table嵌套使用的结构。

<script language=”javascript” type=”text/javascript”>
function client_OnTreeNodeChecked()
{
var obj = window.event.srcElement;
// 当前触发事件对象
var treeNodeFound = false;
// 后面解释
var checkedState;
// 选中状态
if (obj.tagName == “INPUT” && obj.type == “checkbox”)
{
var treeNode = obj;
// 当前CheckBox
checkedState = treeNode.checked;
// 当前CheckBox选中状态
do
{
obj = obj.parentElement;
}
while (obj.tagName != “TABLE”)
// 找到当前CheckBox所在的Table

var parentTreeLevel = obj.rows[0].cells.length;
//  当前节点所属层次
//  生成的HTML代码中为了收缩,每加一层加一个TD
//  TD的个数就是节点层次数
var parentTreeNode = obj.rows[0].cells[0];
// 无用处
var tables = obj.parentElement.getElementsByTagName(“TABLE”);
// 当前CheckBox所在的Table隶属的DIV下的所有Table,也就免除了递归
var numTables = tables.length
if (numTables >= 1)
{
for (i=0; i < numTables; i++)
{
if (tables[i] == obj)
{// 当前CheckBox所在的Table是其隶属的DIV下有多个Table
// 但是当前CheckBox所在节点的子节点所在table的Id均比当前节点大
// 只有先找到当前节点才去置其子节点的Checked属性
treeNodeFound = true;
// 找到当前CheckBox所在的Table
i++;
// 当前CheckBox不用处理
if (i == numTables)
{// 如果没有字节点结束
return;
}
}
if (treeNodeFound == true)
{
var childTreeLevel = tables[i].rows[0].cells.length;
if (childTreeLevel > parentTreeLevel)
{
var cell = tables[i].rows[0].cells[childTreeLevel - 1];
// 数组从0开始计数,CheckBox在最后一个Td中
var inputs = cell.getElementsByTagName(“INPUT”);
inputs[0].checked = checkedState;
// 置CheckBox状态
}
else
{
return;
}
}
}
}
}
}
</script>
<script language=”javascript” type=”text/javascript”>
function Result(v_stf_id,v_stf_name)
{
this.stf_id = v_stf_id;
this.stf_name=v_stf_name;
}

function GetSelecteStf()
{
var rtn=new Array();

var obj=document.getElementById(“stfTreen0Nodes”);

var parentTreeLevel=0 ;
//  当前节点所属层次
//  生成的HTML代码中为了收缩,每加一层加一个TD
//  TD的个数就是节点层次数
var tables = obj.parentElement.getElementsByTagName(“TABLE”);
//  当前CheckBox所在的Table隶属的DIV下的所有Table,也就免除了递归
var numTables = tables.length
if (numTables >= 1)
{
for (i=0; i < numTables; i++)
{
var currentTreeLevel= tables[i].rows[0].cells.length;
var cell = tables[i].rows[0].cells[currentTreeLevel - 1];
var inputs = cell.getElementsByTagName(“INPUT”);
if(inputs[0].checked )
{// 父节点选中
if(i+1 < numTables)
{// 跟下一个节点的深度比较
// 如果这个节点深度大于等于下一个节点深度
// 那么这个节点就是最底层节点
var nextTreeLevel = tables[i+1].rows[0].cells.length;
if(currentTreeLevel >= nextTreeLevel)
{// 该节点是最底层节点
var herf= cell.getElementsByTagName(“A”);
rtn.push(new Result(GetNodeValue(herf[0]),herf[0].innerHTML));
}
}
else
{// 这个节点本身就是最后一个节点,肯定是最底层节点
var herf= cell.getElementsByTagName(“A”);
rtn.push(new Result(GetNodeValue(herf[0]),herf[0].innerHTML));
}
}
}
}
return rtn;
}
function GetNodeValue(obj)
{
var content=obj;
content =”#”+content;
var ids= content.match(/\d+/g);
return ids[ids.length-1];
}
</script>


3 Comments

leo Windows XP Internet Explorer 8.0 on 2009年01月14日 at 10:37.

很好很强大!

回复

KattyBlackyard Windows Me Internet Explorer 6.0 on 2009年06月15日 at 23:45.

I really like your post. Does it copyright protected?

回复

Felix Windows XP Google Chrome 2.0.172.31 on 2009年06月17日 at 20:14.

about this post , i find lots of references such as MSDN
and got source code from code.google.com ,so i have no idea that it copyright protected or not!

but other posts of my blog just my own opinion that is may copyright protected!

回复

Leave Your Comment

Your email will not be published or shared. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>