数据展示
数据源绑定 需要设置KeyFieldName和ParentFieldName后绑定数据treeList1.DataSource = dataTable1;
且KeyFieldName列不能存在重复的数据
手动增加节点
注:该方法有多个重载,可灵活设置节点的父节点,图标,勾选状态,tag等
设置node上的数据
外观
自定义设置节点的图标(需要绑定一个imageCollection给TreeList的SelectImageList)其他外观设置基本都在OptionsView下面,可以设置:
是否显示行头,列头,水平线,垂直线,勾选框等。
OptionsFind下可以设置搜索栏的显示方式,是否显示搜索,清空按钮等。但是这个自带的搜索比较鸡肋,当一个节点满足条件,但是其父节点不满足条件时这个节点也无法显示。
除非事先调用treeList1.ExpandAll();将节点全部展开显示,当数据比较大的时候也是比较麻烦的,后面会介绍一种自定义的方法。
拖曳操作
如果需要从外面拖入数据,需要设置treeList1.AllowDrop = true;
如果需要内部拖曳节点,需要设置
treeList1.OptionsBehavior.DragNodes = true;
相关的几个事件:
DragEnter——当拖曳进入到treeList中时
DragOver——相当于在treeList上的MouseMove
DragDrop——拖曳结束松开鼠标时
DragLeave——拖曳节点出treeList时
从外部控件(比如GridControl)拖曳数据到树上,流程:
//1
Grid的MouseMove事件判断是否左键按下,执行treeList1.DoDragDrop(yourData, DragDropEffects.Copy);
//2
treeList的DragEnter事件,执行e.Effect = DragDropEffects.Copy;//可以执行判断,如果不满足可赋值DragDropEffects.None禁止拖曳操作
//3
treeList的DragDrop事件,获取数据e.Data.GetData(typeof(YourType)) as YourType,并判断当前节点:
var hi = treeListMaster.CalcHitInfo(treeListMaster.PointToClient(new Point(e.X, e.Y)));
var targetNode = hi.Node;
此处可通过hi.HitInfoType判断当前拖放的位置,是Cell,Column,Row,StateImage,Button,FilterPanel,ScrollBar,CheckBox....
然后执行treeList1.AppendNode(...);即可。
将树节点拖出控件执行删除操作,想当然地在DragLeave中操作,问题来了:
1.操作后,treeList依然认为在执行Drag操作,除非找到一个时机将DragDropEffects置为None;
2.体验不好,鼠标刚刚离开树,还没抬起左键,提示的MessageBox就弹出来了,不是想要的效果;
多次实验后还是换为另一种思路(这其实是DevExpress的Demo):
在treeList外部放置一个label,图标设置为垃圾桶:
树内部拖曳,移动或节点排序也可以在DragDrop中操作
然后保存这个顺序即可。
问题来了:如何判断是移动节点还是排序?在拖曳的时候树控件虽然会提示箭头(向上/下表示移动,向右表示加为子节点),但是在DragDrop的代码中却无法判断这个状态。
无奈只好改为其他的事件来处理移动节点和节点排序:
AfterDragNode——拖曳节点结束后触发
通过比对dragNode的拖曳前后的父节点,判断是排序还是移动节点。
其他的还有DragObjectDrop,这个名字比较坑,其实只在拖曳treeListColumn时触发。
节点搜索过滤
前面提到treeList提供了OptionsFind,可以展示一个Find框,可以将任何匹配的文字高亮,如果打开了FilterNode选项还可以实现节点过滤。但是存在一个问题:如果某节点匹配条件,但其父节点不匹配,该节点仍被过滤掉。除非在Find之前将树全部展开treeList1.ExpandAll();明显我们不希望这样。
根据DevExpress的官方答复,他们会在后续版本中提供一个新的OptionsFilter.FilterMode:Extended,但是目前的版本还没有。
实现方法,放置一个ButtonEdit在树控件的上方,并实现一个FilterNodeOperation类: