博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
带线的无限级下拉树列表-完整示例篇
阅读量:6948 次
发布时间:2019-06-27

本文共 5316 字,大约阅读时间需要 17 分钟。

前言:

今天在群里有人问起了我一个比较远古的问题:他运行不起来。
最关键的又扯上了,让我一时觉得比较悬,因为文章是08年时写的,而框架最今年才发力完善的,
所以两者应该是没啥联系的,不过这一问也好,给了我一个写此文章的机会。
ps:他把示例的其它代码当成是  里的代码。

 

 

本文将对之前的代码进行小小的简化,并为之建立一个完整的应用示例,以下为正式应用步骤:

 

一:新建项目

1:将IDropDownTree及DropDownTree放到类里,如下图:

简化后的代码如下:

IDropDownTree

ExpandedBlockStart.gif
IDropDownTree
using
 System.Collections.Generic;
using System;
namespace
 Tree
{
    
public
 
interface
 IDropDownTree : IDisposable
    {
        
///
 
<summary>
        
///
 返回Dictionary里分别对应ID,文本,如果没有子节点返回null
        
///
 
</summary>
        
///
 
<param name="parentID">
父节点ID
</param>
        
///
 
<returns></returns>
        Dictionary
<
string
string
>
 GetChildList(
string
 parentID);
        
///
 
<summary>
        
///
 实现的代码里写return new Tree.DropDownTree(this);
        
///
 
</summary>
        DropDownTree DropDownTree
        {
            
get
;
        }
    }
}

 

DropDownTree

ExpandedBlockStart.gif
DropDownTree
using
 System.Collections.Generic;
using
 System.Web.UI.WebControls;
namespace
 Tree
{
    
public
 
sealed
 
class
 DropDownTree
    {
        IDropDownTree _DropDownTree;
        
public
 DropDownTree(IDropDownTree dropDownTree)
        {
            _DropDownTree 
=
 dropDownTree;
        }
        
///
 
<summary>
        
///
 用于树的前缀
        
///
 
</summary>
        
///
 
<param name="IsLast">
是否是同级节点中的最后一个
</param>
        
///
 
<param name="HasChild">
本节点是否拥有子节点
</param>
        
///
 
<param name="ParentString">
父节点前缀符号
</param>
        
///
 
<returns>
本节点的前缀
</returns>
        
private
 
string
 GetPreFix(
bool
 isLast, 
bool
 hasChild, 
string
 parentString)
        {
            
string
 result 
=
 
string
.Empty;
            
if
 (
!
string
.IsNullOrEmpty(parentString))
            {
                parentString 
=
 parentString.Remove(parentString.Length 
-
 
1
).Replace(
"
"
"
"
).Replace(
"
"
"
 
"
);
                result 
+=
 parentString;
            }
            result 
+=
 isLast 
?
 
"
"
 : 
"
"
;
            result 
+=
 hasChild 
?
 
"
"
 : 
"
"
;
            
return
 result;
        }
        
#region
 绑定下拉菜单
        
///
 
<summary>
        
///
 绑定连动级的下拉菜单
        
///
 
</summary>
        
///
 
<param name="ddlGoodsType">
传进一个被绑定的DropDownList
</param>
        
///
 
<param name="removeID">
被排除绑定的节点ID
</param>
        
public
 
void
 Bind(ListControl dropDown, 
string
 removeID, 
string
 parentID)
        {
            
            ListItem listItem 
=
 
null
;
            
string
 currentID 
=
 parentID;
//
根节点/父ID
            
string
 currentSign 
=
 
string
.Empty;
//
当前节点符号;
            
string
 parrentSign 
=
 
string
.Empty; 
//
父节点符号;
            
bool
 HasChild 
=
 
true
;
//
是否有子
            Queue
<
string
>
 parentKeyList 
=
 
new
 Queue
<
string
>
();
//
存 有子节点的 节点ID
            Queue
<
string
>
 parentSignList 
=
 
new
 Queue
<
string
>
();
//
对应节点ID的前缀符号
            
int
 itemIndexOf 
=
 
0
;
//
父节点所在的位置 
            
while
 (HasChild)
            {
                
int
 lastOneCount 
=
 
1
;
//
用于计算在同级别中是否最后一个
                Dictionary
<
string
string
>
 childList 
=
 _DropDownTree.GetChildList(currentID);
//
 得到子节点列表
                
if
 (childList 
!=
 
null
)
                {
                    
if
 (
!
string
.IsNullOrEmpty(removeID) 
&&
 childList.ContainsKey(removeID))
                    {
                        childList.Remove(removeID);
                    }
                    
foreach
 (KeyValuePair
<
string
string
>
 entry 
in
 childList)
                    {
                        
if
 (_DropDownTree.GetChildList(entry.Key) 
!=
 
null
)
//
存在子
                        {
                            currentSign 
=
 GetPreFix(lastOneCount 
==
 childList.Count, 
true
, parrentSign);
                            listItem 
=
 
new
 ListItem(currentSign 
+
 entry.Value, entry.Key);
                            parentKeyList.Enqueue(entry.Key);
//
当前的节点ID
                            parentSignList.Enqueue(currentSign);
//
当前的节点符号
                        }
                        
else
//
不存在子
                        {
                            currentSign 
=
 GetPreFix(lastOneCount 
==
 childList.Count, 
false
, parrentSign);
                            listItem 
=
 
new
 ListItem(currentSign 
+
 entry.Value, entry.Key);
                        }
                        
if
 (dropDown.Items.Count 
!=
 
0
)
                        {
                            itemIndexOf 
=
 
string
.IsNullOrEmpty(currentID) 
?
 itemIndexOf 
+
 
1
 : dropDown.Items.IndexOf(dropDown.Items.FindByValue(currentID)) 
+
 lastOneCount;
                        }
                        dropDown.Items.Insert(itemIndexOf, listItem);
//
添加子节点
                        lastOneCount
++
;
                    }
                    
if
 (parentKeyList.Count 
>
 
0
)
//
存在子节点时
                    {
                        currentID 
=
 parentKeyList.Dequeue();
                        parrentSign 
=
 parentSignList.Dequeue();
                    }
                    
else
                    {
                        HasChild 
=
 
false
;
                    }
                }
                
else
                {
                    
break
;
                }
            }
            _DropDownTree.Dispose();
        }
        
#endregion
    }
}

 

二:数据库数据准备

1:为方便示例,这里用了Access数据库,新建一个Product表,并为之添加了几行数据,如图:

 

三:引用CYQ.Data框架来实现

1:项目添加CYQ.Data引用

2:新建ProductTree类,实现IDropDownTree接口

A:为表增加枚举,如下:

namespace
 Entity
{
    
public
 
enum
 TableNames
    {
        Product
    }
    
public
 
enum
 Product
    {
        ID,
        ParentID,
        Name
    }
}

 

B:实现接口

ExpandedBlockStart.gif
using
 Tree;
using
 CYQ.Data;
using
 Entity;
using
 CYQ.Data.Table;
using
 System.Collections.Generic;
namespace
 Tree
{
    
///
 
<summary>
    
///
 作者:路过秋天
    
///
 博客:
http://cyq1162.cnblogs.com
    
///
 秋色园:
http://www.cyqdata.com
    
///
 
</summary>
    
public
 
class
 ProductTree : IDropDownTree
    {
        
int
 count 
=
 
0
;
        
private
 MAction action;
        
public
 ProductTree()
        {
            action 
=
 
new
 MAction(TableNames.Product);
        }
        
#region
 IDropDownTree 成员
        
public
 Dictionary
<
string
string
>
 GetChildList(
string
 parentID)
        {
            MDataTable table 
=
 action.Select(
0
0
"
ParentID=
"
 
+
 parentID, 
out
 count);
            Dictionary
<
string
string
>
 dic 
=
 
null
;
            
if
 (count 
>
 
0
)
            {
                dic 
=
 
new
 Dictionary
<
string
string
>
();
                
foreach
 (MDataRow row 
in
 table.Rows)
                {
                    dic.Add(row.Get
<
string
>
(Product.ID), row.Get
<
string
>
(Product.Name));
                }
            }
            
return
 dic;
        }
        
public
 DropDownTree DropDownTree
        {
            
get
            {
                
return
 
new
 DropDownTree(
this
);
            }
        }
        
#endregion
        
#region
 IDisposable 成员
        
public
 
void
 Dispose()
        {
            action.Close();
        }
        
#endregion
    }
}

项目解决方案如下图:

 

四:展示应用结果

1:新建测试站点WebDemo项目,并将数据库放到App_Data目录下,如图:

2:Web.config配置好数据库链接如下:

ExpandedBlockStart.gif
<
appSettings
>
    
<
add 
key
="AccessDbNameForWeb"
 value
="App_Data/tree.mdb"
/>
</
appSettings
>
<
connectionStrings
>
    
<
add 
name
="Conn"
 connectionString
="Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}"
 providerName
="System.Data.OleDb"
/>
</
connectionStrings
>

 

3:Default.界面调用代码

前台:

放一下拉框:
<
asp:DropDownList 
ID
="ddlProduct"
 runat
="server"
></
asp:DropDownList
>

 

后台:

 
protected
 
void
 Page_Load(
object
 sender, EventArgs e)
 {
     
new
 Tree.ProductTree().DropDownTree.Bind(ddlProduct,
null
"
0
"
);
 }

 

4:最后的输出结果,如图

 

最后提示:

1:提供示例源码下载:-- [最近很少写文,点击下载的你别忘了点下推荐哦^-^]]

2:秋色园V2.5将在近期发布,欢迎提前浏览

转载地址:http://snenl.baihongyu.com/

你可能感兴趣的文章