2008年4月29日 星期二

TreeView DataWindow設計(ㄧ)

開發工具:powerbuilder 6.5
雖然powerbuilder 10.5已經提供了TreeView DataWindow的功能了

畫面也是標準的DataWindow介面,感覺上也很好用?(我還沒用過啦)。可是呢,目前公司提供的工具最高也僅到PB10而已,大多數的程式和工具也都是維持在PB6.5的版本;而且許多朋友也是還在使用PB6.5苦撐...唉!公司預算有限嘛!能用且用囉。

這讓我興起想要建立自己的TreeViewDataWindow物件的想法。雖然說powerbuilder本身就有treeView的物件,但是那不是DataWindow的型態,所以列印的話效果都不好,也很難控制。
難怪powerbuilder敢誇海口DataWindow是MIS開發報表最方便的工具。

由於DataWindow由於名稱過長,因此文中如果有遇到DataWindow如果有遇到字樣的可能會以DW表示。

《一》首先,先來了解一下樹狀結構吧,樹狀結構顧名思義,一定跟樹....有關係 XD
如果把它的葉子全部脫光光........
這樣只剩下之枝幹與枝節,然後再把它右轉90度,是不是很像下面的圖....

那麼這就是所謂樹狀結構圖了,具有相同性質的"節點",每個節點底下還可以再分更多節點,由於看起來像樹一樣,所以就稱為樹狀結構。當然,如果你要表現成TreeView的話,這樣是不行的,因為treeView比較接近條列式,像是下圖:

比較井然有序,比較條列,大部份若要製作成報表,就要使用此種表現方式的報表比較容易看懂。以上的簡單說明主要牽涉到資料存放的方式,如果你對樹狀結構不夠明瞭,那麼當下面設計TreeView的資料結構時候,你就會很難理解。

《二》了解你的開發工具,雖然學PB的很多人都會使用DataWindow,但是對於DataWindow的運作原理卻不是很熟悉。當然這裡不會介紹DataWindow的原理,而是利用其特性去建構成我們要展現的DataWindow。

這個物件主要是裡用DataWindow的屬性建構,因此主要使用modify這個指令來建構DWO(DataWindow Object)。DataWindow本身可說是一個Paint Container,而這個Container包含了幾個區塊:group、detail、header、fotter、summary,個區塊(band)各有不同展現屬性,這裡不對此進行詳述。而當我們建立(Create) DWO時主要是建立在detail band上的。因為在列印上Detail Band才有分頁的效果,若是建立在Header、Summary、Footer上的話要調整報表就是一件麻煩事了(有興趣的可以自己試試看)。

《三》規劃:
雖然我是在DW上產生TreeView的DWO,但是其實每個DWO都有其屬性(Properties),例如基本屬性:ID(id)、Parent ID(pid)、Name(text),延伸屬性:X、Y、Width、Height、Depth(level)、Expanded Flag、Picture Name等等相當的多。所以使用要產生TreeView本身的DW來承接資料是有技術上的問題,而且如果希望到時候能夠在畫面編輯資料,就更需要保留當作Paint Container的DW本身的column。

因此我使用一個DataStore(ids_node)去記錄其TreeView的資料屬性:
利用這樣的方式,在操作上只要維持這個DataStore的資料正確性,就可以讓TreeView DW正確的畫出該有的樹狀圖。

而這個DataStore的資料排列就跟樹狀結構的順序有相當重要的關係,底下舉個例子:
左邊是TreeView DW顯示的樣子,右邊是其內部資料node properties(DataStore)儲存資料的樣子
發現了有趣的事情了嗎?DataStore的"紀錄順序"居然與TreeView的"展現順序"是相同的,因此DataStore的資料等於是Treeview DataWindow的"內部"資料樣式。

"層"的概念:
其實"樹狀"概念落實在資料儲存中也不過是"資料順序"+"階層"而已,因此內部資料主要是給程式作為繪製TreeView的依據,因此繪製node物件時便是參考此node所存在的"層"數來計算相對位置,所以TreeView DW只需負責"展現"繪製的工作:
因此理論上使用者不需要也不可以去介入這個DataStore的任何運作方式,僅能透過公共(Public)函式來進行TreeView的操作,從另一方面來說,資料的建立與新增主要是針對DataStore來實行的,如此TreeView DW的設計就會比較單純。

再來討論一下這個TreeView DW應該具備的可呼叫功能(提供外部使用者設計使用)應該有哪些:
(1)增加節點項目 of_AddItem
(2)項目展開 of_Expand
(3)項目收合 of_Collapse
(4)尋找項目 of_FindItem
(5)取得項目的父項目 of_Item_Parent
(6)清除TreeView of_Reset

供外部使用事件:
(1) 使用者點擊項目時 ue_ItemClicked

這些設計的功能僅是"基本"產生TreeView的使用所需要功能,其他延伸功能有時間可以自行再研究看看。當然,實際運作時不會僅有上述的Function及Event,當然還有內部使用的Function與Event,因此這部份留待實作時(續篇)再來分析。

0 個回應: