最近由於項目的關系,對Microsoft在各種編程語言中提供的TreeView控件做了一些研究。最初在網上查了一下,除了Microsoft的MSDN有些分散的knowledge, 並沒有發現有這方面主題文章,於是有了寫這篇文章的想法,希望可以拋磚引玉,讓後來人少走些彎路。
出於個人興趣的關系,我主要對Microsoft Visual C++ 和C#兩種語言中的TreeView控件進行了相應的研究,在這兩種語言中,對於TreeView控件的基本用法本文不做說明,相對高級的用法主要是為TreeItem設置靜態圖標和選中圖標,drag and drop操作,由於C#中的TreeView控件是所有微軟提供的TreeView控件中相對完整,而且設計相對優雅的一個,下面以C#中TreeView控件為例就相應的主題分別說明。
先來看看MSDN上給C# TreeView控件的定義:
Displays a hierarchical collection of labeled items, each represented by a TreeNode.
翻譯:表現一組有繼承結構關系的帶有標簽的項的集合,每個標簽項由TreeNode來表現。也就是說TreeNode表現樹的節點,主要工作由它來承擔。
那麼如何為TreeNode設置圖像呢?
如下文字來自MSDN:
可以在樹節點旁顯示圖像,方法是將一個ImageList 分配給ImageList 屬性,然後通過引用Image 在ImageList 中的索引值來分配該Image。
使用下面的屬性分配圖像:
將ImageIndex 屬性設置為當樹節點未選定時所顯示的Image 的索引值。
將SelectedImageIndex 屬性設置為當樹節點被選定時要顯示的Image 的索引值。
ImageIndex 和SelectedImageIndex 屬性值所引用的圖像是所有分配給Nodes 集合的樹節點顯示的默認圖像。 每個樹節點都可以通過設置TreeNode.ImageIndex 和TreeNode.SelectedImageIndex 屬性來取代默認的圖像。
看完了這段文字,你知道該如何操作了麼?我覺得可能有好多人還是不是完全的理解,那我們就已程序員的語言來描述一下吧:
首先定義一個ImageList變量並將其賦值給TreeView的ImageList,
1 private System.Windows.Forms.ImageList imageList007;
2 this.imageList007 = new System.Windows.Forms.ImageList(this.components);
3 this.treeView1.ImageList = this.imageList007;
然後需要對圖標進行設置,
this.imageList007.ImageStream =
((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList007.ImageStream")));
this.imageList007.TransparentColor = System.Drawing.Color.Transparent;
this.imageList007.Images.SetKeyName(0, "Icon01.ico");
this.imageList007.Images.SetKeyName(1, "Icon02.ico");
this.imageList007.Images.SetKeyName(2, "Icon03.ico");
this.imageList007.Images.SetKeyName(3, "Icon04.ico");
this.imageList007.Images.SetKeyName(4, "Icon05.ico");
最後可以對TreeView 的ImageIndex 和SelectedImageIndex 屬性進行相應的設置,選擇相應的圖像,也可以對每個動態生成的節點進行獨立的圖像設置,到此你已經成功的設置了TreeNode的圖像。
那又如何實現Drag and Drop 操作呢?
首先我們需要清楚Drag and Drop的源和目標都是什麼,也就是說從哪向哪拖拽,每個部分承擔的職責是什麼,而只有在源和目標上都做了相應的處理,拖拽過程才可能是完整有效的。
源組件處理:
ItemDrag事件: 當鼠標開始對源樹節點進行拖拽的時候,會引發這個事件,也就是說這個事件的發出者應該是源組件, 在這個事件處理函數中需要調用DoDragDrop方法 初始化並開始一個拖拽過程。
目標組件處理:
DragEnter事件: 當初始化操作結束以後,我們需要在拖拽目標處處理DragEnter事件,這個事件發生在源節點被拖動到目標組件范圍內的某個點的時候,在這個事件中我們可以對這個拖拽的合法性進行驗證,並且設置不同的鼠標形狀來表示不同的狀態,DragDropEffects 結構用於對鼠標形狀進行設置。
目標組件處理:
DragDrop 事件: 這個事件用於在目標組件中處理拖拽事件,發生於源節點已經被拖拽到目的組件處,這時我們可以對拖拽過來的節點進行解析處理等實際工作。
注意:為了完成拖拽操作源組件和目標組件的AllowDrop都需要設置成true.
示例代碼,如下代碼完成了將一個TreeNode拖拽到一個Form上需要完成的工作:
private void UsingTreeViewDemo_Load(object sender, EventArgs e)
{
this.treeView1.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.treeView_ItemDrag);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form_DragEnter);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form_DragDrop);
}
private void treeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
{
DoDragDrop(e.Item, DragDropEffects.Copy);
}
private void Form_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void Form_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
TreeNode NewNode;
if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
{
NewNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
MessageBox.Show(NewNode.ToString());
}
}
至此,本文的使命已經完成,相信大家已經熟悉了這兩項相對高級的TreeView用法。歡迎大家就此主題互相討論,並對本文的不當之處批評指正。
作者 SolidMango