下面,我們來看看插件的實現(xiàn),首先,參考《探索 Word 2007 開發(fā)(一):我的博客》這篇文章里提到的方法在Visual Studio 2008 Beta 2中創(chuàng)建一個項目骨架,里面包含一個空白的Ribbon(取名ReflinksRibbon)和一個空白的User Control(取名TocView),并在TocView上放置一個TreeView控件:
圖 2
我不打算用普通的TreeNode來填充這個TreeView,而是使用根據(jù)MTPS的節(jié)點模型創(chuàng)建的自定義節(jié)點類來填充,當然,這個自定義節(jié)點類繼承自TreeNode類:
Code 1
TOC全稱Table of Content,TocNode與MTPS的TOC導航節(jié)點模型向?qū)?
TocNode.Text:節(jié)點標簽(Label),對應于toc:Title;
TocNode.Target:與該導航節(jié)點對應的內(nèi)容節(jié)點的標識符,對應于toc:Target;
TocNode.Locale:與該導航節(jié)點對應的內(nèi)容節(jié)點的區(qū)域信息,例如zh-CN,對應于toc:TargetLocale;
TocNode.Version:與該導航節(jié)點對應的內(nèi)容節(jié)點的版本信息,例如VS.90,對應于toc:TargetVersion;
TocNode.SubTree:如果該導航節(jié)點包含子節(jié)點,則該屬性為子節(jié)點樹片斷的標識符,對應于toc:SubTree。
我希望使用《TreeView 四技》這篇文章里提到的延遲填充技巧,并讓節(jié)點自行負責子節(jié)點的填充,如果某個節(jié)點擁有子節(jié)點,它也必須負責通知TreeView對其做出適當?shù)匿秩。下面是通過MTPS獲取當前節(jié)點的子節(jié)點(注意,MTPS僅返回下一級的子節(jié)點):
Code 2
我們可以通過檢查SubTree是否為null知道當前節(jié)點有否子節(jié)點,然而,我們還是無從得知子節(jié)點的裝載是否已經(jīng)執(zhí)行過。重復裝載無疑導致不必要的網(wǎng)絡訪問,于是,我為TocNode添加了一個類型為bool的m_Loaded字段。這樣,僅當SubTree不為null以及m_Loaded不為false時,我們才裝載子節(jié)點。所有這些操作都是在用戶點擊節(jié)點前面那個+號時才執(zhí)行的,但由于子節(jié)點還沒填充,TreeView是不會為該節(jié)點渲染+ 號的,于是,我們需要為該節(jié)點添加一個"占位子節(jié)點",以便TreeView能夠正確渲染。添加占位子節(jié)點的最佳時機是當我們給SubTree屬性賦值時,所以我把SubTree屬性修改如下:
Code 3
有了這些準備,我們就可以實現(xiàn)Load()方法來裝載子節(jié)點了:
Code 4
這個方法將會在TreeView的BeforeExpand事件委托里調(diào)用:
Code 5
值得提醒的是,當子節(jié)點填充完畢后,別忘了刪除之前加入的占位子節(jié)點,并把m_Loaded的值設為true。另外,這里使用了GetAttribute()輔助方法來獲取XAttribute的值:
Code 6
這樣,TreeView的填充就變成簡單地添加一個根節(jié)點了,這將在TocView的Load事件委托里完成: