电竞比分网-中国电竞赛事及体育赛事平台

分享

在Visual FoxPro中使用TreeView控件

 悟靜 2009-07-19
如果用戶在設計程序時,需要用一種樹形結構生動形象地顯示具有不同層次的數據,那么TreeView控件將是最合適的選擇。TreeView控件可以將用戶選定的數據,也可以是從數據庫中檢索出來的數據,供用戶自由的選擇、展開或折迭收起。TreeView控件主要用以顯示層次數據之間的關系。TreeView控件的特點包括以下幾個方面:
1、將相互間有聯(lián)系的數據用圖形與文字方式以樹形描繪,以樹形節(jié)點(Node對象)的形式展開或收起數據;
2、每一個節(jié)點可以用圖標和文本標簽來描述;
3、標簽可以設置為是否允許修改的屬性;
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屬性的介紹中再詳細說明任何解決這個問題。
一、Node對象的屬性
在控件上單擊右鍵,單擊彈出式菜單的最后一項即可修改屬性。

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對象的相對位置關系。
relationship值的設置如下:
常量 描述
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é)點
④Key:Node對象的鍵值。必須是字符串。
⑤Text:Node對象的標簽。必須是字符串。
⑥Image:可選參數。與ImageList控件關聯(lián)的圖像索引或鍵值,也就是標簽前面的圖標。
⑦Selectedimage:可選參數。當Node對象選中時,所顯示的與ImageList控件關聯(lián)的圖像索引或鍵值。比如:節(jié)點未選中時顯示關閉的文件夾圖標,選中時顯示打開的文件夾圖標。
2、Remove:從Node集合(Nodes)中刪除一個節(jié)點。該節(jié)點的子節(jié)點將被一同刪除(如果有的話)。
語法:Object.Nodes.Remove(Key)
①Object:對象名稱,本例為ThisForm.Tree。
②Key:Node對象的鍵值。
3、Nodes( ):用Node對象的索引返回對象的引用。
語法:Object.Nodes(Index)
①Object:對象名稱,本例為ThisForm.Tree。
②Index:增加一個Node對象時給其分配的索引值。第一個加入的節(jié)點Index為1,第二個為2,依次類推。
4、Nodes( ):用Node對象的鍵值返回對象的引用。
語法:Object.Nodes(Key)
①Object:對象名稱,本例為ThisForm.Tree。
②Key: Node對象的鍵值。
三、事件
1、BeforeLabelEdit:在試圖編輯當前選中的Node對象標簽時該事件發(fā)生。在LabelEdit=1時該事件失效。
2、AfterLabelEdit:在編輯當前選中的Node對象標簽后事件發(fā)生。在LabelEdit=1時該事件失效。
3、Collapse:將已展開的節(jié)點折疊時事件發(fā)生。該事件發(fā)生在標準的Click事件之前。該事件返回被折疊的Node對象的引用。觸發(fā)Collapse事件有三種方法:
①設置Node對象的Expanded屬性為False.;
②雙擊展開的Node對象;
③TreeView控件的Style屬性為2、3、6或7時,單擊“-”圖象。
4、Expand:在控件有子節(jié)點的Node對象擴展開時事件發(fā)生。該事件發(fā)生在標準的Click事件之前。該事件返回被展開的Node對象的引用。觸發(fā)Expanded事件有三種方法:
①設置Node對象的Expanded屬性為True.;
②雙擊帶有子節(jié)點的Node對象;
③TreeView控件的Style屬性為2、3、6或7時,單擊“+”圖象。
5、NodeClick:單擊Node對象時該事件發(fā)生。該事件發(fā)生在標準的Click事件之前。在單擊節(jié)點對象之外的控件任何部位,標準的Click事件發(fā)生。
四、舉例
1、用表中數據增加節(jié)點。該表有_Parent(父節(jié)點鍵值),_Key(本節(jié)點鍵值),Text(節(jié)點文本),3個字段。
select LS
SCAN
IF ALLTRIM(parent) = "0"
Node = this.nodes.add(,1,ALLTRIM(LS.key),ALLTRIM(LS.Text),,)
*加入根節(jié)點
ELSE
Node =this.nodes.add(ALLTRIM(LS.parent),4,ALLTRIM(LS.key),ALLTRIM(LS.Text),,)
ENDIF
ENDSCAN
2、將所有節(jié)點信息存入一個臨時表。該例將控件每一個節(jié)點的鍵值(_key)、標簽(T_text)和父節(jié)點鍵值(_parent)存入臨時表:LS。
O=ThisForm.Tree
*為了減少代碼數量,建立一個對象變量來代替很長的對象名稱。
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)
Endfor
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))
Select LS2
node_index=o.SelectedItem.Index *Tree1當前選定的節(jié)點索引值
*下面代碼獲取該節(jié)點的父節(jié)點
Do while .t.
Insert Into Ls2 Value(o.Nodes(node_index).Index)
If o.Nodes(node_index).Parent.Index=1
Exit
Endif
node_index=o.Nodes(node_index).Parent.Index
Enddo
*由于上面代碼獲取的父節(jié)點排在子節(jié)點的后面,下面這個循環(huán)把順序倒過來,使輩分高的節(jié)點排在前面。
Do while .t.
Go Bottom
node_index=LS2._index
If node_index=0
Exit
Endif
Insert Into LS1 Value(o.Nodes(node_index).Parent.Key,;
o.Nodes(node_index).Key,;
o.Nodes(node_index).Text)
Delete
Enddo
Select LS2
child_number=o.SelectedItem.Children
If Child_number>0
node_index=o.SelectedItem.Index
Do while node_index#0
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)
For i=2 to child_number
node_index=LS2._index
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)
Endfor
Select LS2
Go Bottom
Do while .t.
node_index=LS2._index
If node_index=0
Exit
Endif
child_number=o.Nodes(node_index).Children
If child_number=0
Delete
Go Bottom
Loop
Else
Delete
Exit
Endif
Enddo
Go Bottom
Enddo
Endif
Select Ls2
Use
五、其它:
1、TreeView控件缺少一個檢測節(jié)點是否存在的函數(不知道是不是我沒有發(fā)現(xiàn)),當向一個控件加入一個節(jié)點時,如果鍵值重復就會出錯。有一個辦法“解決”問題,我暫且稱之為“賴皮”算法,就是用On Error Lerror=.T.忽略所有錯誤,之后再用On Error 解除就會相安無事。見下例。如果沒有第一行,當檢測的節(jié)點不存在時,就會有錯誤窗口彈出。
On Error Lerror=.T.
If Isnull(Thisform.Tree.Nodes(Key))
On Error
Return(.f.)
Else
On Error
Return(.T.)
Endif
2、最后簡要介紹ImagesList控件的使用方法。
ImageList控件與TreeView控件都在文件Mscomctl.ocx中。在表單運行時該控件不可見,它的任務就是向其他控件提供圖標。設計時在控件上單擊鼠標右鍵,會彈出一個快捷菜單,單擊“ImageListCtrl Properties”就會出現(xiàn)一個標題為“ImageListCtrl 屬性”的窗口,在這個窗口中可以設置控件的屬性。在這里先設置圖標的大小,加入圖標后大小就無法改變了。加入圖標并指定圖標的索引或鍵值后,就可以由其他控件隨意調用圖標了。5.0版的ImageList控件只能加入圖標,6.0版的可以加入圖片(當然不能太大),所以盡可能使用高版本

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多