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