天天看點

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.     if (index.ToString() != string.Empty)  
  5.     {  
  6.         e.SelectImageIndex = Convert.ToInt32(index);  
  7.     }  
  8. }  

其他外觀設定基本都在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. private void labelControl1_DragDrop(object sender, DragEventArgs e)  
  7. {  
  8.     //這裡執行删除節點操作  
  9.     DeleteNode();  
  10.     labelControl1.Appearance.ImageIndex = 0;//換為關閉的垃圾桶  
  11. }  
  12. private void labelControl1_DragLeave(object sender, EventArgs e)  
  13. {  
  14.     labelControl1.Appearance.ImageIndex = 0;//換位關閉的垃圾桶  
  15. }  

樹内部拖曳,移動或節點排序也可以在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.     public FilterNodeOperation(string _pattern)  
  5.     {  
  6.         pattern = _pattern;  
  7.     }  
  8.     public override void Execute(TreeListNode node)  
  9.     {  
  10.         if (NodeContainsPattern(node, pattern))  
  11.         {  
  12.             node.Visible = true;  
  13.             //if (node.ParentNode != null)  
  14.             //    node.ParentNode.Visible = true;  
  15.             //必須要遞歸查找其父節點全部設定為可見  
  16.             var pNode = node.ParentNode;  
  17.             while (pNode != null)  
  18.             {  
  19.                 pNode.Visible = true;  
  20.                 pNode = pNode.ParentNode;  
  21.             }  
  22.         }  
  23.         else  
  24.             node.Visible = false;  
  25.     }  
  26.     bool NodeContainsPattern(TreeListNode node, string pattern)  
  27.     {  
  28.         foreach (TreeListColumn col in node.TreeList.VisibleColumns)  
  29.         {  
  30.             if (node.GetDisplayText(col).Contains(pattern))  
  31.                 return true;  
  32.         }  
  33.         return false;  
  34.     }  
  35. }  
  36. //在ButtonEdit的ButtonClick事件中執行這個Operation:  
  37. private void buttonEdit1_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)  
  38. {  
  39.     var operation = new FilterNodeOperation(buttonEdit1.EditValue != null ? buttonEdit1.EditValue.ToString() : "");  
  40.     treeListMaster.NodesIterator.DoOperation(operation);  
  41. }

原文位址 http://blog.csdn.net/davinciyxw/article/details/40779573

繼續閱讀