一个继承于DropDownList的树状控件
由于工作需要特扩展了一下已有的DropDownList控件,使其能显示树状结构的数据,主要用于那些有层次关系的数据显示
由于工作需要特扩展了一下已有的DropDownList控件,使其能显示树状结构的数据,主要用于那些有层次关系的数据显示。
如下图所示:
该控件为无限级扩展的,只需要指定其子节点字段名(默认为ID),父节点字段名(默认为parentID),以及第一层父节点的值即可(默认为0)。
1.首先定义常量
2.添加属性
3.计算当前节点所在的层以及是否为子节点,是否有兄弟节点等函数,用于生成树形
4.递归生成树形
5.绑定数据
请大家多多指教以便改进,谢谢!
如下图所示:
该控件为无限级扩展的,只需要指定其子节点字段名(默认为ID),父节点字段名(默认为parentID),以及第一层父节点的值即可(默认为0)。
1.首先定义常量
protected const string strT="├";
protected const string strL="└";
protected const string strI="│";
protected DataTable tempTable;
protected int lay = 0;//节点层数
protected int level=0;//DropDownList顺序
protected const string strL="└";
protected const string strI="│";
protected DataTable tempTable;
protected int lay = 0;//节点层数
protected int level=0;//DropDownList顺序
2.添加属性
属性
[Category("数据"),Description("第一层父节点的值")]
public int FirstParentValue
{
get
{
object obj=ViewState["FirstParentValue"];
return ((obj==null)?0:(int)obj);
}
set
{
ViewState["FirstParentValue"]=value;
}
}
[Category("数据"),Description("子字段名")]
public string ChildField
{
get
{
object obj=ViewState["ChildField"];
return ((obj==null)?"ID":(string)obj);
}
set
{
ViewState["ChildField"]=value;
}
}
[Category("数据"),Description("父字段名")]
public string ParentField
{
get
{
object obj=ViewState["ParentField"];
return ((obj==null)?"parentID":(string)obj);
}
set
{
ViewState["ParentField"]=value;
}
}
[Category("数据"),Description("显示文本字段名")]
public string ShowText
{
get
{
object obj=ViewState["ShowText"];
return ((obj==null)?"name":(string)obj);
}
set
{
ViewState["ShowText"]=value;
}
}
[Category("数据"),Description("第一层父节点的值")]
public int FirstParentValue
{
get
{
object obj=ViewState["FirstParentValue"];
return ((obj==null)?0:(int)obj);
}
set
{
ViewState["FirstParentValue"]=value;
}
}
[Category("数据"),Description("子字段名")]
public string ChildField
{
get
{
object obj=ViewState["ChildField"];
return ((obj==null)?"ID":(string)obj);
}
set
{
ViewState["ChildField"]=value;
}
}
[Category("数据"),Description("父字段名")]
public string ParentField
{
get
{
object obj=ViewState["ParentField"];
return ((obj==null)?"parentID":(string)obj);
}
set
{
ViewState["ParentField"]=value;
}
}
[Category("数据"),Description("显示文本字段名")]
public string ShowText
{
get
{
object obj=ViewState["ShowText"];
return ((obj==null)?"name":(string)obj);
}
set
{
ViewState["ShowText"]=value;
}
}
3.计算当前节点所在的层以及是否为子节点,是否有兄弟节点等函数,用于生成树形
生成树形时要用的函数
/**//// <summary>
/// 递归算出指定ID所在树中的层数
/// </summary>
/// <param name="treeTable"></param>
/// <param name="ID">节点ID</param>
private void FindLay(DataTable treeTable,int ID)
{
for(int i=0;i<treeTable.Rows.Count;i++)
{
if (ID == int.Parse(treeTable.Rows[i][this.ChildField].ToString()))
{
int parentID = int.Parse(treeTable.Rows[i][this.ParentField].ToString());
// 如果父节点不是根节点,递归
if(parentID != 0)
{
lay ++;
FindLay(treeTable,int.Parse(treeTable.Rows[i][this.ParentField].ToString()));
}
}
}
}
/**//// <summary>
/// 判断是否有子接点
/// </summary>
/// <param name="dt"></param>
/// <param name="ID">当前节点的ID</param>
/// <returns></returns>
private bool IsExistChildNodes(DataTable dt,string ID)
{
bool flag=false;
if(ID==null)
return flag;
for(int i=0;i<dt.Rows.Count;i++)
{
if(dt.Rows[i][this.ParentField].ToString()==ID)
{
flag=true;
return flag;
}
else
{
flag=false;
}
}
return flag;
}
/**//// <summary>
/// 判断是否有兄弟节点
/// </summary>
/// <param name="dt"></param>
/// <param name="ID">当前节点的ID</param>
/// <returns></returns>
private bool IsBorthorNodes(DataTable dt,string ID)
{
bool flag=false;
if(ID==null)
return flag;
for(int i=0;i<dt.Rows.Count;i++)
{
if(dt.Rows[i][this.ChildField].ToString()==ID&&i<dt.Rows.Count-1)
{
if(dt.Rows[i][this.ParentField].ToString()==dt.Rows[i+1][this.ParentField].ToString())
{
flag=true;
return flag;
}
else
{
flag=false;
return flag;
}
}
}
return flag;
}
/**//// <summary>
/// 判断当前节点是否为子节点
/// </summary>
/// <param name="dt"></param>
/// <param name="ID"></param>
/// <returns></returns>
private bool IsChildNode(DataTable dt,string ID)
{
bool flag=false;
if(ID==null)
return flag;
for(int i=0;i<dt.Rows.Count;i++)
{
if(dt.Rows[i][this.ChildField].ToString()==ID)
{
if(dt.Rows[i][this.ParentField].ToString()=="0")
{
flag=false;
return flag;
}
else
{
flag=true;
return flag;
}
}
}
return flag;
}
/**//// <summary>
/// 递归算出指定ID所在树中的层数
/// </summary>
/// <param name="treeTable"></param>
/// <param name="ID">节点ID</param>
private void FindLay(DataTable treeTable,int ID)
{
for(int i=0;i<treeTable.Rows.Count;i++)
{
if (ID == int.Parse(treeTable.Rows[i][this.ChildField].ToString()))
{
int parentID = int.Parse(treeTable.Rows[i][this.ParentField].ToString());
// 如果父节点不是根节点,递归
if(parentID != 0)
{
lay ++;
FindLay(treeTable,int.Parse(treeTable.Rows[i][this.ParentField].ToString()));
}
}
}
}
/**//// <summary>
/// 判断是否有子接点
/// </summary>
/// <param name="dt"></param>
/// <param name="ID">当前节点的ID</param>
/// <returns></returns>
private bool IsExistChildNodes(DataTable dt,string ID)
{
bool flag=false;
if(ID==null)
return flag;
for(int i=0;i<dt.Rows.Count;i++)
{
if(dt.Rows[i][this.ParentField].ToString()==ID)
{
flag=true;
return flag;
}
else
{
flag=false;
}
}
return flag;
}
/**//// <summary>
/// 判断是否有兄弟节点
/// </summary>
/// <param name="dt"></param>
/// <param name="ID">当前节点的ID</param>
/// <returns></returns>
private bool IsBorthorNodes(DataTable dt,string ID)
{
bool flag=false;
if(ID==null)
return flag;
for(int i=0;i<dt.Rows.Count;i++)
{
if(dt.Rows[i][this.ChildField].ToString()==ID&&i<dt.Rows.Count-1)
{
if(dt.Rows[i][this.ParentField].ToString()==dt.Rows[i+1][this.ParentField].ToString())
{
flag=true;
return flag;
}
else
{
flag=false;
return flag;
}
}
}
return flag;
}
/**//// <summary>
/// 判断当前节点是否为子节点
/// </summary>
/// <param name="dt"></param>
/// <param name="ID"></param>
/// <returns></returns>
private bool IsChildNode(DataTable dt,string ID)
{
bool flag=false;
if(ID==null)
return flag;
for(int i=0;i<dt.Rows.Count;i++)
{
if(dt.Rows[i][this.ChildField].ToString()==ID)
{
if(dt.Rows[i][this.ParentField].ToString()=="0")
{
flag=false;
return flag;
}
else
{
flag=true;
return flag;
}
}
}
return flag;
}
4.递归生成树形
递归生成树形
/**//// <summary>
/// 数据添加并生成树形
/// </summary>
/// <param name="dt"></param>
/// <param name="ID"></param>
private void BindData(DataTable dt,string ID)
{
DataRow[] dr;
dr=dt.Select(this.ParentField+"="+ID,this.ChildField+" ASC");
for(int x=0;x<dr.Length;x++)
{
string str="";
lay=0;
this.FindLay(dt,int.Parse(dr[x][this.ChildField].ToString()));
if(this.IsChildNode(dt,dr[x][this.ChildField].ToString())==true)
{
for(int i=0;i<lay;i++)
{
str+=strI;
}
if(this.IsBorthorNodes(dt,dr[x]["id"].ToString())==true)
{
this.Items.Insert(level,new ListItem(str+strT+dr[x][this.ShowText].ToString(),dr[x][this.ChildField].ToString()));
}
else
{
this.Items.Insert(level,new ListItem(str+strL+dr[x][this.ShowText].ToString(),dr[x][this.ChildField].ToString()));
}
}
else
{
this.Items.Insert(level,new ListItem(str+dr[x][this.ShowText].ToString(),dr[x][this.ChildField].ToString()));
}
level+=1;
this.BindData(dt,dr[x][this.ChildField].ToString());//递归生成树
}
}
/**//// <summary>
/// 数据添加并生成树形
/// </summary>
/// <param name="dt"></param>
/// <param name="ID"></param>
private void BindData(DataTable dt,string ID)
{
DataRow[] dr;
dr=dt.Select(this.ParentField+"="+ID,this.ChildField+" ASC");
for(int x=0;x<dr.Length;x++)
{
string str="";
lay=0;
this.FindLay(dt,int.Parse(dr[x][this.ChildField].ToString()));
if(this.IsChildNode(dt,dr[x][this.ChildField].ToString())==true)
{
for(int i=0;i<lay;i++)
{
str+=strI;
}
if(this.IsBorthorNodes(dt,dr[x]["id"].ToString())==true)
{
this.Items.Insert(level,new ListItem(str+strT+dr[x][this.ShowText].ToString(),dr[x][this.ChildField].ToString()));
}
else
{
this.Items.Insert(level,new ListItem(str+strL+dr[x][this.ShowText].ToString(),dr[x][this.ChildField].ToString()));
}
}
else
{
this.Items.Insert(level,new ListItem(str+dr[x][this.ShowText].ToString(),dr[x][this.ChildField].ToString()));
}
level+=1;
this.BindData(dt,dr[x][this.ChildField].ToString());//递归生成树
}
}
5.绑定数据
绑定数据
/**//// <summary>
/// 绑定数据
/// </summary>
/// <param name="dt">数据源DataTable</param>
public void BindListData(DataTable dt)
{
tempTable=dt.Clone();
this.BindData(dt,this.FirstParentValue.ToString());
}
使用的时候调用该函数进行数据绑定!
/**//// <summary>
/// 绑定数据
/// </summary>
/// <param name="dt">数据源DataTable</param>
public void BindListData(DataTable dt)
{
tempTable=dt.Clone();
this.BindData(dt,this.FirstParentValue.ToString());
}
请大家多多指教以便改进,谢谢!