DevExpress控件XtraTreeList的使用心得

数据展示

数据源绑定 需要设置KeyFieldName和ParentFieldName后绑定数据
treeList1.DataSource = dataTable1;
且KeyFieldName列不能存在重复的数据
手动增加节点
[csharp]  view plain  copy
  1. var node = treeList1.AppendNode(""null);  
注:该方法有多个重载,可灵活设置节点的父节点,图标,勾选状态,tag等
设置node上的数据
[csharp]  view plain  copy
  1. node.SetValue(treeListColumn1, obj1);  
  2. node.Tag = obj2;  

外观

自定义设置节点的图标(需要绑定一个imageCollection给TreeList的SelectImageList)
[csharp]  view plain  copy
  1. private void treeListMaster_CustomDrawNodeImages(object sender, DevExpress.XtraTreeList.CustomDrawNodeImagesEventArgs e)  
  2. {  
  3.     var index = e.Node.GetValue("IMAGEINDEX");  
  4.   
  5.   
  6.     if (index.ToString() != string.Empty)  
  7.     {  
  8.         e.SelectImageIndex = Convert.ToInt32(index);  
  9.     }  
  10. }  
其他外观设置基本都在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,图标设置为垃圾桶:        
[csharp]  view plain  copy
  1. private void labelControl1_DragEnter(object sender, DragEventArgs e)  
  2. {  
  3.     e.Effect = DragDropEffects.Copy;  
  4.     labelControl1.Appearance.ImageIndex = 1;//换为打开的垃圾桶  
  5. }  
  6.   
  7.   
  8. private void labelControl1_DragDrop(object sender, DragEventArgs e)  
  9. {  
  10.     //这里执行删除节点操作  
  11.     DeleteNode();  
  12.     labelControl1.Appearance.ImageIndex = 0;//换为关闭的垃圾桶  
  13. }  
  14.   
  15.   
  16. private void labelControl1_DragLeave(object sender, EventArgs e)  
  17. {  
  18.     labelControl1.Appearance.ImageIndex = 0;//换位关闭的垃圾桶  
  19. }  

树内部拖曳,移动或节点排序也可以在DragDrop中操作

[csharp]  view plain  copy
  1. treeList1.SetNodeIndex(dragnode, treeList1.GetNodeIndex(targetnode));  

然后保存这个顺序即可。
问题来了:如何判断是移动节点还是排序?在拖曳的时候树控件虽然会提示箭头(向上/下表示移动,向右表示加为子节点),但是在DragDrop的代码中却无法判断这个状态。
无奈只好改为其他的事件来处理移动节点和节点排序:
AfterDragNode——拖曳节点结束后触发
通过比对dragNode的拖曳前后的父节点,判断是排序还是移动节点。

其他的还有DragObjectDrop,这个名字比较坑,其实只在拖曳treeListColumn时触发。


节点搜索过滤

前面提到treeList提供了OptionsFind,可以展示一个Find框,可以将任何匹配的文字高亮,如果打开了FilterNode选项还可以实现节点过滤。但是存在一个问题:
如果某节点匹配条件,但其父节点不匹配,该节点仍被过滤掉。除非在Find之前将树全部展开treeList1.ExpandAll();明显我们不希望这样。
根据DevExpress的官方答复,他们会在后续版本中提供一个新的OptionsFilter.FilterMode:Extended,但是目前的版本还没有。
实现方法,放置一个ButtonEdit在树控件的上方,并实现一个FilterNodeOperation类:

[csharp]  view plain  copy
  1. class FilterNodeOperation : TreeListOperation  
  2. {  
  3.     string pattern;  
  4.   
  5.   
  6.     public FilterNodeOperation(string _pattern)  
  7.     {  
  8.         pattern = _pattern;  
  9.     }  
  10.   
  11.   
  12.     public override void Execute(TreeListNode node)  
  13.     {  
  14.         if (NodeContainsPattern(node, pattern))  
  15.         {  
  16.             node.Visible = true;  
  17.               
  18.             //if (node.ParentNode != null)  
  19.             //    node.ParentNode.Visible = true;  
  20.               
  21.             //必须要递归查找其父节点全部设置为可见  
  22.             var pNode = node.ParentNode;  
  23.             while (pNode != null)  
  24.             {  
  25.                 pNode.Visible = true;  
  26.                 pNode = pNode.ParentNode;  
  27.             }  
  28.         }  
  29.         else  
  30.             node.Visible = false;  
  31.     }  
  32.   
  33.   
  34.     bool NodeContainsPattern(TreeListNode node, string pattern)  
  35.     {  
  36.         foreach (TreeListColumn col in node.TreeList.VisibleColumns)  
  37.         {  
  38.             if (node.GetDisplayText(col).Contains(pattern))  
  39.                 return true;  
  40.         }  
  41.         return false;  
  42.     }  
  43. }  
  44. //在ButtonEdit的ButtonClick事件中执行这个Operation:  
  45. private void buttonEdit1_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)  
  46. {  
  47.     var operation = new FilterNodeOperation(buttonEdit1.EditValue != null ? buttonEdit1.EditValue.ToString() : "");  
  48.     treeListMaster.NodesIterator.DoOperation(operation);  
  49. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值