zoukankan      html  css  js  c++  java
  • 带线的无限级下拉树列表

    前言:

    今天在群里有人问起了我一个比较远古的问题:带线的无限级下拉树列表他运行不起来。

    最关键的又扯上了CYQ.Data 框架,让我一时觉得比较悬,因为文章是08年时写的,而框架最今年才发力完善的,

    所以两者应该是没啥联系的,不过这一问也好,给了我一个写此文章的机会。

    ps:他把示例的其它代码当成是 CYQ.Data 框架 里的代码。

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

    一:新建项目

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

    简化后的代码如下:

    IDropDownTree

    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<stringstring> GetChildList(string parentID);

            
    /// <summary>
            
    /// 实现的代码里写return new Tree.DropDownTree(this);
            
    /// </summary>
            DropDownTree DropDownTree
            {
                
    get;
            }
        }
    }

    DropDownTree

    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<stringstring> childList = _DropDownTree.GetChildList(currentID);// 得到子节点列表
                    if (childList != null)
                    {
                        
    if (!string.IsNullOrEmpty(removeID) && childList.ContainsKey(removeID))
                        {
                            childList.Remove(removeID);
                        }
                        
    foreach (KeyValuePair<stringstring> 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:实现接口

    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<stringstring> GetChildList(string parentID)
            {

                MDataTable table 
    = action.Select(00"ParentID=" + parentID, out count);
                Dictionary
    <stringstring> dic = null;
                
    if (count > 0)
                {
                    dic 
    = new Dictionary<stringstring>();
                    
    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配置好数据库链接如下:

    <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:最后的输出结果,如图

    最后提示:

  • 相关阅读:
    我的未来。
    我的的第一篇博客
    从软件工程角度回顾本科毕业论文
    从高级软件工程角度分析毕业设计-小结-盛超
    从软件工程视角,回顾分析本科毕业设计软件中存在的不足问题
    从软件工程的角度分析本科毕业设计
    从高级软件工程角度分析本科毕业设计
    从软件工程的视角,回顾本科毕业设计,探视设计中存在的不足
    用软件工程思想看毕业设计
    从软件工程角度分析毕业设计
  • 原文地址:https://www.cnblogs.com/zlf344242525/p/2274637.html
Copyright © 2011-2022 走看看