天天看點

C# ComboBox 下拉顯示層次(樹)

資料庫中很多時候用到樹形結構,在界面上顯示時如果是下拉框一次性顯示時需要樹結構來展現,看個效果圖先:

C# ComboBox 下拉顯示層次(樹)

主要是用算法補空格,補符号,源碼如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        private List<profile> pList;
        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            pList = new List<profile>();
            pList.AddRange(new profile[] { 

                 new profile { Id = 1, parentId=0, value="A級"}, 
                 new profile { Id = 2, parentId=0, value="A級"}, 
                 new profile { Id = 3, parentId=0, value="A級"}, 
                 new profile { Id = 4, parentId=0, value="A級"}, 
                 new profile { Id = 5, parentId=0, value="A級"}, 

                 new profile { Id = 6, parentId=1, value="B級"},
                 new profile { Id = 7, parentId=2, value="B級"}, 
                 new profile { Id = 8, parentId=2, value="B級"}, 
                 new profile { Id = 9, parentId=4, value="B級"}, 
                 new profile { Id = 10, parentId=3, value="B級"}, 
                 
               

                new profile { Id = 11, parentId=7, value="C級"}, 
                new profile { Id = 12, parentId=7, value="C級"},  
                new profile { Id = 13, parentId=9, value="C級"}, 
                new profile { Id = 14, parentId=9, value="C級"}, 
                new profile { Id = 15, parentId=10, value="C級"}, 
                new profile { Id = 16, parentId=10, value="C級"}, 
                
                new profile { Id = 17, parentId=13, value="D級"}, 
                new profile { Id = 18, parentId=13, value="D級"},  
                new profile { Id = 19, parentId=12, value="D級"}, 

                
               
               new profile { Id = 20, parentId=17, value="E級"}, 
               new profile { Id = 21, parentId=18, value="E級"},
               new profile { Id = 22, parentId=18, value="E級"},  

               new profile { Id = 23, parentId=21, value="F級"},                 
               new profile { Id = 24, parentId=23, value="G級"}, 
               new profile { Id = 25, parentId=24, value="H級"}, 


                new profile { Id = 26, parentId=12, value="D級"},                 
               new profile { Id = 27, parentId=26, value="E級"}, 
               new profile { Id = 28, parentId=27, value="F級"}, 
                

            });


            //執行個體化一個根節點
            profile rootRoot = new profile();
            rootRoot.Id = 0;
            rootRoot.parentId = 0;
            rootRoot.name = "頂級";

            AppendChildren(pList, rootRoot, 0);

            List<string> _name = new List<string>();
            getName(rootRoot, _name);
            ArrayList list = new ArrayList();
            for (int i = 0; i < _name.Count; i++) {
                list.Add(new System.Collections.DictionaryEntry(i, _name[i]));
            }
            comboBox1.DataSource = list;
            comboBox1.DisplayMember = "Value";
            comboBox1.ValueMember = "Key";


            //用treeView控件顯示
            var node = new TreeNode("頂級");
            this.AddTree(node, 0);
            this.treeView1.Nodes.Add(node);

            return;
        }
        public void AddTree(TreeNode parentNode, int parentId) {
            var selectedList = pList.FindAll(item => item.parentId == parentId);
            foreach (var group in selectedList) {
                var node = parentNode.Nodes.Add(group.Id.ToString(), group.value);
                AddTree(node, group.Id);
            }
        }

        private List<int> tag = new List<int>();
        private void getName(profile p, List<string> name) {

            //this.listBox1.Items.Add(string.Format("{0}-{1}", p.Id, p.parentId));
            if (p == null) return;
            var str = string.Empty;


            for (var i = 1; i < p.level; i++) {
                if (tag.Contains(i)) {
                    str += "    ";
                } else {
                    str += "│  ";
                }
            }
            name.Add(string.Format("{0}{1}{2}", str, p.name, p.value, p.parentId, p.Id, p.level));
            for (int i = 0; i < tag.Count; i++) {
                if (tag[i] >= p.level) {
                    tag.Remove(tag[i]);
                }
            }
            if (p.tag == 0) tag.Add(p.level);
            if (p.profileList != null && p.profileList.Count > 0) {
                foreach (profile x in p.profileList) {
                    getName(x, name);
                }
            }
        }





        public void AppendChildren(List<profile> list, profile profile, int count) {
            try {
                count++;
                var id = profile.Id;
                var subItems = list.Where(ee => ee.parentId == id).ToList();
                if (subItems.Count > 0) {
                    for (int i = 0; i < subItems.Count; i++) {
                        if (i == subItems.Count - 1) {
                            subItems[i].name = string.Format("{0}{1}", "└--", "");
                        } else {
                            subItems[i].name = string.Format("{0}{1}", "├--", "");
                        }
                        subItems[i].level = count;
                        subItems[i].tag = i == subItems.Count - 1 ? 0 : 1;
                    }

                    profile.profileList = new List<profile>();
                    profile.profileList.AddRange(subItems);
                }
                foreach (var subItem in subItems) {
                    AppendChildren(list, subItem, count);
                }
            } catch (Exception e) {
                MessageBox.Show(e.Message);
            }
        }
    }

    public class profile {
        public string fill { get; set; }
        public int tag { get; set; }
        public string name { get; set; }
        public int Id { get; set; }
        public int parentId { get; set; }
        public string value { get; set; }
        public int level { get; set; }
        public List<profile> profileList { get; set; }
    }
}