天天看點

動态載入資料的無重新整理TreeView控件(1)

雖然使用腳本制作的TreeView已經有很多了,不過對于做自己的産品來說,要使用現成的控件是很困難的。首先要能免費授權,其次需要有自己所期望的所有功能,三需要代碼清晰到能很快了解并修改。免費可能是最簡的要求了,而功能和可修改性卻就不容易了,是以最後自己實作一個反而更省事。微軟的Microsoft.Web控件包裡有個強大的TreeView,不過遺憾的是那個是背景資料邦定的,Expand或Collapse節點需要doPostBack操作:(。

    既然開始都說了,現成的TreeView很多了,那麼這個TreeView就必須站在巨人的肩膀上了。首先圖示資源就不用自己弄了

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

制作這個菜單,最重要的有兩點,資料結構和UI表現(當然還有操作,不過這是以前者為基礎的)。TreeView的資料結構,其實和Menu那個非常的相似,一個Tree類,一個TreeNode類,然後互相組合嵌套就可以了。隻是在顯示上需要有個合理的子樹縮進,略顯比菜單麻煩,因為菜單都是相對Parent菜單條目定位。UI表現使用Table元素來做為菜單整體,每一行TR元素作為一個菜單條目。這都不是難點,而最困難的是子樹的層次縮進,從目前我所看到的樹控件來講,都是使用類似遞歸的方式來生成樹的層次線條。而由于我前不久做過一個Menu控件,是以非常希望能像Menu那樣,子菜單縮緊隻用關心父菜單條目,那樣實作起來就簡潔多了,于是我設計了這樣一種新的菜單UI元素的擺放層次。

R.A.D樹控件是使用DIV元素來生成樹的UI表現,通過嵌套DIV來實作子樹,不過子樹縮進做的比較郁悶,居然是用一大堆的圖檔來當作SPACE(因為用别的東西不好控制寬度)。我實作的TreeView中,每個Tree層次是完整獨立的,子樹作為一個整體潛入父TreeNode,縮進完全由菜單層次自動維護,就是說每個菜單項生成相同的HTML代碼。

    Tree類的結構:

動态載入資料的無重新整理TreeView控件(1)

 function Tree(attribute, style)

動态載入資料的無重新整理TreeView控件(1)

 {

動态載入資料的無重新整理TreeView控件(1)

    this.Extends(CollectionBase);

動态載入資料的無重新整理TreeView控件(1)

    this.m_Nodes = this.m_InnerArray;

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    this.m_ParentNode = null;

動态載入資料的無重新整理TreeView控件(1)

    this.m_ActiveNode = null;

動态載入資料的無重新整理TreeView控件(1)

    this.m_Element = null;

動态載入資料的無重新整理TreeView控件(1)

    this.m_TreeType = TreeType.Normal;

動态載入資料的無重新整理TreeView控件(1)

    this.m_TreeLevel = 0;

動态載入資料的無重新整理TreeView控件(1)

    this.m_IsEventAttached = false;

動态載入資料的無重新整理TreeView控件(1)

    this.m_Id = __GlobalTreeCache__.NewId();

動态載入資料的無重新整理TreeView控件(1)

    __GlobalTreeCache__[this.m_Id] = this;

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    this.m_Attributes = attribute ? attribute : new TreeAttribute();

動态載入資料的無重新整理TreeView控件(1)

    this.m_Styles = style ? style : new TreeStyle();   

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    this.InsertAt = function(node, index)

動态載入資料的無重新整理TreeView控件(1)

    {

動态載入資料的無重新整理TreeView控件(1)

         this.base.InsertAt.Call(this, node, index);

動态載入資料的無重新整理TreeView控件(1)

         node.m_Tree = this;  

動态載入資料的無重新整理TreeView控件(1)

    };

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    this.toString = function()

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

        return '[class Tree]';

動态載入資料的無重新整理TreeView控件(1)

    };  

動态載入資料的無重新整理TreeView控件(1)

 }

這個結構中,m_TreeLevel是樹的層次數,本來用我這種表格嵌套結構,不需要知道樹中的層次也是可以的,可是如果不知道目前樹的層次是不是Root層,不能正确地生成節點前的操作提示圖示。__GlobalTreeCache__是一個全局Hash

    TreeNodeBase類的結構(TreeNode的所有和UI相關的内容,在TreeNodeBase中生成):

動态載入資料的無重新整理TreeView控件(1)

 function TreeNodeBase(text, action, icon, subtree)

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    this.m_Text = text;

動态載入資料的無重新整理TreeView控件(1)

    this.m_Tooltip = ''; 

動态載入資料的無重新整理TreeView控件(1)

    this.m_Atction = action;

動态載入資料的無重新整理TreeView控件(1)

    if ( subtree )

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

        subtree.m_ParentNode = this;

動态載入資料的無重新整理TreeView控件(1)

        this.m_ChildTree = subtree;

動态載入資料的無重新整理TreeView控件(1)

    }

動态載入資料的無重新整理TreeView控件(1)

    this.m_Tree = null; 

動态載入資料的無重新整理TreeView控件(1)

    this.m_Icon = null;

動态載入資料的無重新整理TreeView控件(1)

    this.m_IconPath = icon;

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    this.m_IsChildExpanded = false;

動态載入資料的無重新整理TreeView控件(1)

    this.m_IsLazyLoad = false;

動态載入資料的無重新整理TreeView控件(1)

    this.m_IsLoaded = false;

動态載入資料的無重新整理TreeView控件(1)

    this.m_Checked = false;

動态載入資料的無重新整理TreeView控件(1)

    this.m_Disabled = false;  

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

        return '[class TreeNodeBase]';

動态載入資料的無重新整理TreeView控件(1)
動态載入資料的無重新整理TreeView控件(1)

    這個類比較清楚,每個屬性的作用都一目了然,就不多說了。

    下一節講TreeAttributes和TreeStyle類。

本文轉自部落格園鳥食軒的部落格,原文連結:http://www.cnblogs.com/birdshome/,如需轉載請自行聯系原部落客。

繼續閱讀