| 如果用戶在設計程序時,需要用一種樹形結構生動形象地顯示具有不同層次的數據,那么TreeView控件將是最合適的選擇。TreeView控件可以將用戶選定的數據,也可以是從數據庫中檢索出來的數據,供用戶自由的選擇、展開或折迭收起。TreeView控件主要用以顯示層次數據之間的關系。TreeView控件的特點包括以下幾個方面: |
| 1、將相互間有聯(lián)系的數據用圖形與文字方式以樹形描繪,以樹形節(jié)點(Node對象)的形式展開或收起數據; |
| 2、每一個節(jié)點可以用圖標和文本標簽來描述; |
| 4、對層次深度和節(jié)點數目無限制,只受系統(tǒng)資源的限制。 |
| 另外,使用TreeView控件對管理信息量很大的數據來說,是一個很好的方式,因為用戶能從中簡單快速的選擇到所需要的數據。Windows資源管理器就是TreeView控件、ImageList控件與ListView控件配合應用的一個例子。 |
| TreeView控件是Microsoft Visual Studio 中的一個控件,它是Mscomctl.ocx文件中的一組ActiveX控件的一部分。當安裝了Visual FoxPro或Visual Basic后就可以在Windows的System目錄中找到這個文件。為了在發(fā)布的應用程序中使用TreeView控件,必須將Mscomctl.ocx文件與應用程序一起做成安裝盤發(fā)布。這個控件在Visual FoxPro 5.0中的版本是5.0,但是該控件的5.0版本不支持6.0版本的一些屬性、方法和事件,所以要盡量使用6.0版本。如果沒有Visual FoxPro 6.0也可以,只要找到Mscomctl.ocx這個文件并將其注冊,就可以在Visual FoxPro 5.0中使用該控件的6.0版本。 |
| 一個TreeView控件由若干Node對象組成,一個Node對象就是一個節(jié)點。一個TreeView控件只能有一個根節(jié)點(Root)。一個節(jié)點有若干子節(jié)點(Child),但必須有(除根節(jié)點以外)也只能有一個父節(jié)點(Parent)。創(chuàng)建TreeView控件之后,可以通過設置屬性與調用方法操作各Node對象,包括添加、刪除等??梢跃幊陶归_與折迭Node對象顯示或隱藏子節(jié)點。 |
| 在FoxPro主菜單的“工具”菜單的“選項”中“控件頁框”,將“ActiveX控件”的“Microsoft TreeView Control,Version 6.0”選定,然后單擊確定,即可將TreeView控件加入“表單控件工具欄”。單擊表單控件工具欄的查看類按鈕,彈出一個菜單,單擊其中的“ActiveX控件”,即可在“表單控件工具欄”看到TreeView控件。將ImageList控件加入“表單控件工具欄”的方法與TreeView控件的方法一樣。 |
| TreeView的外觀只要看一下Windows資源管理器就很清楚了。要使用TreeView控件與其他普通控件一樣,TreeView控件也是由屬性、方法和事件控制的(以下假設表單加入的TreeView控件的Name屬性是Tree)。設計時在控件上單擊鼠標右鍵會彈出一個快捷菜單,單擊“TreeCtrl Properties”就會出現(xiàn)一個標題為“TreeCtrl屬性”的窗口,在這個窗口中可以設置控件的一些屬性。但這里有一個“Bug”,如果在這里設置與ImageList控件的關聯(lián)存不上盤,當時好象存上了,再次打開還是老樣子。在后面Image屬性的介紹中再詳細說明任何解決這個問題。 |
| 在控件上單擊右鍵,單擊彈出式菜單的最后一項即可修改屬性。 |
|
1、Key(鍵值):一個節(jié)點的鍵值必須是唯一的字符型的值,控件用鍵值來區(qū)分節(jié)點,如果某兩個節(jié)點的鍵值相同將會出錯。鍵值可以由字母、下劃線、空格和數字等可打印字符組成,但不能是純數字的字符串,否則會出錯。如用于顯示磁盤目錄,可以用路徑作為鍵值。
ThisForm.Tree.SelectedItem.Key
或
ThisForm.Tree.Nodes.Item(Node.Index).Key 返回控件當前選定的節(jié)點的鍵值。
|
|
2、Parent(父節(jié)點):一個節(jié)點只能有一個父節(jié)點,根節(jié)點沒有父節(jié)點。
ThisForm.Tree.SelectedItem.Parent.Key
返回控件當前選定的節(jié)點的父節(jié)點的鍵值。如果當前選定的節(jié)點沒有父節(jié)點,則這行代碼就會出錯。
可用ThisForm.Tree.SelectdeItem.Parent是否為空值(Isnull)或ThisForm.Tree.SelectedItem.Index是否等于1判斷該節(jié)點是否有父節(jié)點。
|
|
3、Child(子節(jié)點):
ThisForm.Tree.SelectedItem.Child.Key返回TreeView控件中當前選定的節(jié)點的第一個子節(jié)點的鍵值,如果該節(jié)點無子節(jié)點,該行代碼會出錯??梢允褂孟旅孢@個屬性看一下它有沒有子節(jié)點。
|
| 4、Children(子節(jié)點數目):ThisForm.Tree.SelectedItem.Children返回TreeView控件中當前選定的節(jié)點的子節(jié)點的數目。 |
| 5、Text(節(jié)點標簽):該屬性返回用戶所看到的節(jié)點的標簽,不同節(jié)點的標簽允許相同,也可以是空字符串。 |
| 6、LabelEdit:該屬性為0時雙擊標簽,即可編輯標簽。等于1時不可編輯。編輯標簽時會觸發(fā)AfterLabelEdit和BeforeLabelEdit事件。 |
| 7、Singlesel:該屬性為Ture時,被選定的節(jié)點如果有子節(jié)點將自動展開顯示子節(jié)點。 |
| 8、Sorted:當該屬性為Ture時,節(jié)點按字母順序排列。 |
| 9、Expanded:當該屬性為Ture時,表明該節(jié)點是展開的。 |
| 10、Next:返回TreeView控件中同為Node節(jié)點的父節(jié)點的子節(jié)點的下一個兄弟節(jié)點的對象。 |
| 11、Previous:返回TreeView控件中同為Node節(jié)點的父節(jié)點的子節(jié)點的前一個兄弟節(jié)點的對象。 |
| 12、Style:返回或設置圖形類型(圖標、文本、+/-號、直線)以及出現(xiàn)在TreeView控件中每一Node對象上的文本類型。 |
| 設置值 |
說明 |
| 0 |
僅為文本 |
| 1 |
圖標和文本 |
| 2 |
+/-和文本 |
| 3 |
+/-、圖標和文本 |
| 4 |
直線和文本 |
| 5 |
直線、圖標和文本 |
| 6 |
直線、+/-和文本 |
| 7 |
(默認)圖標、直線、+/-和文本 |
|
| 13、Count: Nodes集合中的節(jié)點總數。該屬性是Nodes集合的屬性。 |
| 14、Index:增加一個Node對象時就給其分配了索引值,保存在該Node對象的Index屬性中。新成員的該屬性值也是Nodes集合的Count屬性值。 |
| 15、Image:對應節(jié)點的圖標鍵值。TreeView控件中的圖標是另外一個控件ImageList提供的,在這個控件中為每一個圖標指定一個唯一的鍵值,要改變節(jié)點的圖標只要改變這個屬性就可以了。在Visual FoxPro中TreeView控件有一個Bug,在設計時無法與ImageList相關聯(lián)(在VB中沒有此現(xiàn)象),這個問題可以解決,在表單的Init事件中加入下面三行就可以解決這個Bug(假定加入的ImageLiat控件Name屬性為Images)。 |
| This.Tree.ImageList = This.Images |
| 1、Add:用于向TreeView控件加入節(jié)點 |
| 語法:Object.Add (Relative,Relationship, Key, Text, Image, Selectedimage) |
| ①Object:對象名稱,本例為ThisForm.Tree; |
| ②Relative:可選參數。已存在的Node對象的索引或鍵值。加入根節(jié)點時省略,加入子節(jié)點時是父節(jié)點的鍵值。問題加入同級節(jié)點時可以省掉吧?。。?! |
| ③Relationship:可選參數。指定Node對象的相對位置關系。 |
| 常量 |
值 |
描述 |
| TvwFirst |
0 |
第一個。該Node節(jié)點放在relative命名的所有同級節(jié)點的前面 |
| TvwLast |
1 |
最后一個。該Node節(jié)點放在relative命名的所有同級節(jié)點的最后。后續(xù)增加的節(jié)點可以在該節(jié)點之后 |
| TvwNext |
2 |
(缺?。┫乱粋€。該Node節(jié)點放置在relative命名的節(jié)點之后 |
| TvwPrevious |
3 |
前一個。該Node節(jié)點放置在relative命名的節(jié)點之前 |
| TvwChild |
4 |
子節(jié)點。該Node節(jié)點是relative命名節(jié)點的子節(jié)點 |
|
| ⑥Image:可選參數。與ImageList控件關聯(lián)的圖像索引或鍵值,也就是標簽前面的圖標。 |
| ⑦Selectedimage:可選參數。當Node對象選中時,所顯示的與ImageList控件關聯(lián)的圖像索引或鍵值。比如:節(jié)點未選中時顯示關閉的文件夾圖標,選中時顯示打開的文件夾圖標。 |
| 2、Remove:從Node集合(Nodes)中刪除一個節(jié)點。該節(jié)點的子節(jié)點將被一同刪除(如果有的話)。 |
| 語法:Object.Nodes.Remove(Key) |
| ①Object:對象名稱,本例為ThisForm.Tree。 |
| 3、Nodes( ):用Node對象的索引返回對象的引用。 |
| ①Object:對象名稱,本例為ThisForm.Tree。 |
| ②Index:增加一個Node對象時給其分配的索引值。第一個加入的節(jié)點Index為1,第二個為2,依次類推。 |
| 4、Nodes( ):用Node對象的鍵值返回對象的引用。 |
| ①Object:對象名稱,本例為ThisForm.Tree。 |
| 1、BeforeLabelEdit:在試圖編輯當前選中的Node對象標簽時該事件發(fā)生。在LabelEdit=1時該事件失效。 |
| 2、AfterLabelEdit:在編輯當前選中的Node對象標簽后事件發(fā)生。在LabelEdit=1時該事件失效。 |
| 3、Collapse:將已展開的節(jié)點折疊時事件發(fā)生。該事件發(fā)生在標準的Click事件之前。該事件返回被折疊的Node對象的引用。觸發(fā)Collapse事件有三種方法: |
| ①設置Node對象的Expanded屬性為False.; |
| ③TreeView控件的Style屬性為2、3、6或7時,單擊“-”圖象。 |
| 4、Expand:在控件有子節(jié)點的Node對象擴展開時事件發(fā)生。該事件發(fā)生在標準的Click事件之前。該事件返回被展開的Node對象的引用。觸發(fā)Expanded事件有三種方法: |
| ①設置Node對象的Expanded屬性為True.; |
| ③TreeView控件的Style屬性為2、3、6或7時,單擊“+”圖象。 |
| 5、NodeClick:單擊Node對象時該事件發(fā)生。該事件發(fā)生在標準的Click事件之前。在單擊節(jié)點對象之外的控件任何部位,標準的Click事件發(fā)生。 |
| 1、用表中數據增加節(jié)點。該表有_Parent(父節(jié)點鍵值),_Key(本節(jié)點鍵值),Text(節(jié)點文本),3個字段。 |
| Node = this.nodes.add(,1,ALLTRIM(LS.key),ALLTRIM(LS.Text),,) |
| Node =this.nodes.add(ALLTRIM(LS.parent),4,ALLTRIM(LS.key),ALLTRIM(LS.Text),,) |
| 2、將所有節(jié)點信息存入一個臨時表。該例將控件每一個節(jié)點的鍵值(_key)、標簽(T_text)和父節(jié)點鍵值(_parent)存入臨時表:LS。 |
| *為了減少代碼數量,建立一個對象變量來代替很長的對象名稱。 |
| Create Cursor LS (_key c(10),T_text n(40),_parent c(10)) *創(chuàng)建臨時表LS |
| For I=1 to O.Nodes.count() |
| Insert Into LS Value(O.Nodes(I).Key,O.Nodes(I).Text,O.Nodes(I)._parent.Key) |
| 3、獲取一個節(jié)點的所有父節(jié)點與子節(jié)點,并將其存入一個臨時表LS1。臨時表LS1存入所有節(jié)點的父節(jié)點鍵值(_parent)、本節(jié)點鍵值(_key)和本節(jié)點標簽(T_text)。LS2用來模擬堆棧。 |
| O=ThisForm.Tree1 *建立對象變量既可以減少代碼輸入又可增加可讀性只是速度稍慢 |
| Create Cursor LS1 (_parent c(10),_key c(10),T_text c(60)) |
| Create Cursor LS2 (_index n(10)) |
| node_index=o.SelectedItem.Index *Tree1當前選定的節(jié)點索引值 |
| Insert Into Ls2 Value(o.Nodes(node_index).Index) |
| If o.Nodes(node_index).Parent.Index=1 |
| node_index=o.Nodes(node_index).Parent.Index |
| *由于上面代碼獲取的父節(jié)點排在子節(jié)點的后面,下面這個循環(huán)把順序倒過來,使輩分高的節(jié)點排在前面。 |
| Insert Into LS1 Value(o.Nodes(node_index).Parent.Key,; |
| o.Nodes(node_index).Key,; |
| o.Nodes(node_index).Text) |
| child_number=o.SelectedItem.Children |
| node_index=o.SelectedItem.Index |
| Insert Into LS2 Value(o.Nodes(node_index).Child.Index) |
| Insert Into Ls1 Value(o.Nodes(node_index).Key,; |
| o.Nodes(node_index).Child.Key,; |
| o.Nodes(node_index).Child.Text) |
| Insert Into LS2 Value(o.Nodes(node_index).Next.Index) |
| Insert Into LS1 Value(o.Nodes(node_index).Next.Parent.Key,; |
| o.Nodes(node_index).Next.Key,; |
| o.Nodes(node_index).Next.Text) |
| child_number=o.Nodes(node_index).Children |
| 1、TreeView控件缺少一個檢測節(jié)點是否存在的函數(不知道是不是我沒有發(fā)現(xiàn)),當向一個控件加入一個節(jié)點時,如果鍵值重復就會出錯。有一個辦法“解決”問題,我暫且稱之為“賴皮”算法,就是用On Error Lerror=.T.忽略所有錯誤,之后再用On Error 解除就會相安無事。見下例。如果沒有第一行,當檢測的節(jié)點不存在時,就會有錯誤窗口彈出。 |
| If Isnull(Thisform.Tree.Nodes(Key)) |
| 2、最后簡要介紹ImagesList控件的使用方法。 |
| ImageList控件與TreeView控件都在文件Mscomctl.ocx中。在表單運行時該控件不可見,它的任務就是向其他控件提供圖標。設計時在控件上單擊鼠標右鍵,會彈出一個快捷菜單,單擊“ImageListCtrl Properties”就會出現(xiàn)一個標題為“ImageListCtrl 屬性”的窗口,在這個窗口中可以設置控件的屬性。在這里先設置圖標的大小,加入圖標后大小就無法改變了。加入圖標并指定圖標的索引或鍵值后,就可以由其他控件隨意調用圖標了。5.0版的ImageList控件只能加入圖標,6.0版的可以加入圖片(當然不能太大),所以盡可能使用高版本 |
|