感谢谭振林先生所著《道不远人——深入解析ASP.NET 2.0控件开发》
ASP.NET现在使用的朋友是越来越多了,而其中一些很“方便”的控件事实上在实际使用过程中却不是那么方便。还好,我们有办法改善它们,或者是继承现有控件后扩展,或者是继承Control或者CompositeControl重写一个新的控件。这些方法请参见《道不远人》,小凡用在此书中学到的知识重写了很多控件,今天为大家介绍——AutoCheckTreeView
顾名思义,AutoCheckTreeView是由TreeView继承而来。相信大家都用过TreeView,好处自然不用多说,那我们来回忆批斗一下这个控件的不足之处吧。
一,TreeView控件的节点勾选框不支持父子节点自动勾选,例如下面这个树形结构,并且节点存在CheckBox
--父1
--子1
--孙1
--子2
--孙2
--孙3
如果勾选了“子1”节点,“父1”和“孙1”节点是不能自动勾选的。同样的,如果一个节点取消勾选,该节点的子节点也不能全部取消勾选。诚然,有些时候是不需要这样的功能的,可是,如果需要呢?怎么办?小凡的开发过程中,大概这种需求是55分成。
二,TreeView不支持DataSource的绑定功能
TreeView的DataSource是由父控件继承而来,但是,这个属性在TreeView中毫无用处,浪费了一大资源。而且显然,微软也考虑的并不足够。相信大家在项目开发过程中,很多时候都使用树形结构表来记录树形数据,最简单的情况[菜单主键,父菜单主键,菜单名称],这样就定义成功了一个菜单树形结构。好吧,当做维护界面时,当然就会选择TreeView来进行维护比较方便。然而,如何把数据库数据映射到界面上?现在的做法,唯有使用递归或者其它方法来一层一层架构。如果只有一个界面,那还不错,如果又有其它树形结构数据呢?继续做一次重复代码?不!我们做一个控件支持这样的功能,所有的问题都解决了!
在C#中,树形结构一般会出现下面的两种情况:
1)DataTable记录树形结构
- DataSet ds = new DataSet();
- DataTable dt = new DataTable("table");
- ds.Tables.Add(dt);
- dt.Columns.Add("name");
- dt.Columns.Add("value");
- dt.Columns.Add("id");
- dt.Columns.Add("pid");
- dt.Rows.Add("子1", "sdf", 3, 1);
- dt.Rows.Add("父1", "sdf", 1, 0);
- dt.Rows.Add("子2", "sdf", 5, 2);
- dt.Rows.Add("孙1", "sdf", 4, 3);
- dt.Rows.Add("父2", "sdf", 2, 0);
2)使用扩展自IEnumerable的数据结构,并且对象的Property记录来对应
首先定义一个Class结构
- [Serializable]
- class A
- {
- private string name;
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
- private string value;
- public string Value
- {
- get { return this.value; }
- set { this.value = value; }
- }
- private int id;
- public int Id
- {
- get { return id; }
- set { id = value; }
- }
- private int pid;
- public int Pid
- {
- get { return pid; }
- set { pid = value; }
- }
- public A(string name, string value, int id, int pid)
- {
- this.name = name;
- this.value = value;
- this.id = id;
- this.pid = pid;
- }
- }
然后实例化对象,赋值并放入一个ArrayList中
- ArrayList set = new ArrayList();
- set.Add(new A("子1", "sdf", 3, 1));
- set.Add(new A("父1", "sdf", 1, 0));
- set.Add(new A("子2", "sdf", 5, 2));
- set.Add(new A("孙1", "sdf", 4, 3));
- set.Add(new A("父2", "sdf", 2, 0));
在手上有这样的DataSet(DataTable)或者ArrayList情况下,我们希望能为TreeView设置DataSource后调用DataBind()方法即可完成数据绑定和显示功能。
所以,我们要做的TreeView需要两大功能:节点和其父子自动勾选和取消勾选,数据绑定