VSTO之旅系列(三):自定義Excel UI


本專題概要

  • 引言
  • 自定義任務窗體(Task Pane)
  • 自定義選項卡,即Ribbon
  • 自定義上下文菜單
  • 小結

 

引言

  在上一個專題中為大家介紹如何創建Excel的解決方案,相信大家通過從上面一個專題之后了解了Excel的對象模型,以及Office兩種解決方案的,看完上一個專題之后,肯定很多朋友想為Excel自定義屬於自己的UI界面,例如,有這樣的一些疑問——是否可以使用VSTO來自定義選項卡呢? 是否可以自定義上下文菜單的呢?如果你也有這些疑問的話,相信通過本專題你將會得到答案的,下面就開始我們本專題的介紹。

二、自定義任務窗體

   在使用Word2010的時候我們可以通過左邊的導航來看了解文檔的結構,同時我們也可以在輸入框的地方輸入文字來進行搜索,然而這個左邊的導航就是一個任務窗體,相信通過下面的圖大家可以理解Word中那部分是一個任務窗體:

  但是我們在使用Excel中卻沒有找到類似的任務窗體,這時候大家肯定會有這樣一個疑問——如果我想在Excel也想實現一個自定義任務窗體該怎么辦呢?用VSTO可以幫我們辦到嗎?答案是肯定的。首先先模擬一個需求的,相信大家都知道使用F1是打開一個幫助文檔,但是彈出的幫助文檔是與Excel在不同界面的,所以很多朋友在查閱幫助的文檔的時候都需要縮小Excel文檔來查閱,這樣就顯得有些不方便了,我在使用的時候就想,能不能把幫助文檔繼承在Excel的右邊呢?這樣我們查閱Excel幫助文檔就方便多了,就不要縮小Excel文檔,或在Excel和幫助文檔之間左右切換了。既然有這種需求,我們就有實現它的必要性,下面就具體說說如何實現的:

首先在看具體代碼之前,我向大家分析下實現一個任務窗體的思路:

  • 首先,任務窗體是一個窗體,當然就需要在創建的Excel解決方案中創建一個窗體的了,這里我們創建了一個用戶控件
  • 創建和設計完用戶控件的界面之后,我們就需要把這個用戶控件添加到Excel中去了,然而我們在以前的接觸的開發中,添加控件都是把控件添加到某個幾個中去的,例如WinForm中要向窗體添加一個button按鈕,就需要把這個button添加進Controls集合中,同樣VSTO也提供這樣一個把任務面板添加進去的集合—— Microsoft.Office.Tools.CustomTaskPaneCollection,我們可以通過 Globals.ThisAddIn.CustomTaskPanes這行代碼來獲得這個集合,然后調用Add方法就可以把我們自定義的任務面板添加進Excel中了。
  • 添加進去之后,我們還需要使任務面板顯示出來,這樣就涉及了Visible屬性了,確實 Microsoft.Office.Tools.CustomTaskPane 也有Visible屬性

  有了上面的分析過程之后,相信大家看下面的代碼會比較容易理解,另外注意的一點是,因為我們要實現的幫助文檔的任務窗體,由於幫助文檔是在瀏覽器中顯示的,這樣我們就需要集成一個瀏覽器到我們的創建的用戶控件中的,大家看到瀏覽器這個詞可千萬不要覺得有所畏懼,因為微軟提供了WebBrowser控件來幫助我們實現,對於瀏覽器的更多內容可以參看我的這篇博客:自定義Web瀏覽器, 自定義任務窗體的代碼如下:

 public partial class ThisAddIn
    {
        // 定義一個任務窗體
        internal Microsoft.Office.Tools.CustomTaskPane helpTaskPane;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            // 把自定義窗體添加到CustomTaskPanes集合中
            // ExcelHelp 是一個自定義控件類
            helpTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(new ExcelHelp(""), "Excel Help");
          
            // 使任務窗體可見
            helpTaskPane.Visible = true;
            // 通過DockPosition屬性來控制任務窗體的停靠位置,
            // 設置為 MsoCTPDockPosition.msoCTPDockPositionRight這個代表停靠到右邊,這個值也是默認值
            //helpTaskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionRight;
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }
    }

三、自定義選項卡,即Ribbon

 上面實現的任務窗體在Excel一打開的時候就會顯示停靠在Excel的右邊,如下圖所示:

  然而當我們點擊任務窗體中的"X"按鈕就是關閉任務窗體,關閉之后就有一個問題,如果我們又想把幫助任務窗體顯示出來怎么辦呢?因為在Word中的導航窗體也不是一開始就顯示的(有些朋友可能打開的Word文檔沒有導航窗體),此時我們通過勾選視圖選項卡中 “導航窗格”或點擊開始選項卡中的查找按鈕來顯示導航窗體:

此時,我們就想在Excel中是否可以自定義一個選項卡,通過選項卡中按鈕來顯示/隱藏 Excel的幫助任務窗體呢?下面就具體介紹如何創建一個自定義選項卡:

  1. 右鍵你的Excel項目,添加—>新建項,在彈出的添加新項窗口中選擇 "功能區(可視化設計器)" 
  2. 輸入名稱之后單擊添加按鈕
  3. 設計選項卡UI界面,本例子中添加了一個toggleButton.

通過上面的步驟就可以創建一個自定義選項卡,這種方式創建的選項卡在Excel項目(針對的是外接Excel項目類型)啟動的時候就會被加載。

下面具體介紹了如何設計選項卡(即Ribbon):

  1. 設計RibbonTab,首先把ControlIdType屬性設置為Custom,不然我們設計的RibbonGroup部分將會在加載項選項卡下,然后設置Name為HelpTab,這樣我們創建的選項卡才會成為一個新的選項卡,如果我們想把ToggleButton放在Home選項卡下顯示,此時我們只需要把ControlIdType設置為Office,然后把OfficeId設置為TabHome, 具體情況大家可以測試看看的,關於Office 中內置的Control ID 列表,大家可以從下面這個鏈接下載:  

    2007 Office System Document: Lists of Control IDs 

  2. 從工具箱中拖出一個ToggleButton,把Label屬性設置為Help,並把ControlSize屬性設置為RibbonControlSizeLarge:

 

  3. 雙擊 Help ToggleButton按鈕,實現它的單擊事件:

  // 幫助選項卡中toggleButton的單擊事件
        private void toggleHelpBtn_Click(object sender, RibbonControlEventArgs e)
        {
            // 通過toggleHelpButton的選中狀態來控制幫助任務欄的顯示和隱藏
            Globals.ThisAddIn.helpTaskPane.Visible = toggleHelpBtn.Checked;
        }

  通過上面的三步也就完成了一個Ribbon的創建了,當我們創建好一個Ribbon之后,我們可以通過我們自定義的Ribbon下的按鈕來顯示/隱藏我們的任務窗體,但是到這里,Ribbon的開發並沒有結束,此時還有一個問題就是——當我們點擊 “Excel help”右上角的X按鈕關閉時,我們Ribbon下的按鈕狀態也要跟着更變(大家可以測試,當我們關閉Word中的導航任務窗體時,試圖下的"導航窗格"復選框“也會跟着改變),此時我們就需要實現:點擊關閉按鈕與Help按鈕狀態同步的功能的,此時我們只需要對TaskPane的VisibleChanged事件進行處理就可以(因為關閉任務窗體就會觸發該事件,所以只需要把同步狀態的代碼放在該事件就可以了),具體代碼如下:

// 定義一個任務窗體
        internal Microsoft.Office.Tools.CustomTaskPane helpTaskPane;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            // 把自定義窗體添加到CustomTaskPanes集合中
            // ExcelHelp 是一個自定義控件類
            helpTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(new ExcelHelp(""), "Excel Help");
          
            // 使任務窗體可見
            //helpTaskPane.Visible = true;
            // 通過DockPosition屬性來控制任務窗體的停靠位置,
            // 設置為 MsoCTPDockPosition.msoCTPDockPositionRight這個代表停靠到右邊,這個值也是默認值
            //helpTaskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionRight;
            
            // 當用戶點擊 “Excel help”右上角的X按鈕關閉時,我們需要同步選項卡上button的狀態 
            helpTaskPane.VisibleChanged += new EventHandler(helpTaskPane_VisibleChanged);

            // 添加上下文菜單
            //AddToCellMenu();
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }
       
        // 用戶點擊 "Excel Help" 側邊欄右上角的X按鈕關閉它時 // 我們需要正確同步 “幫助”按鈕的狀態 // 我們可以通過處理 “Excel Help”側邊欄的VisualChanged 事件完成
        private void helpTaskPane_VisibleChanged(object sender, EventArgs e) { // 獲得Help Ribbon 對象
            Help helpRibbon = Globals.Ribbons.GetRibbon<Help>(); // 同步Help Ribbon下的"幫助"按鈕的狀態
            helpRibbon.toggleHelpBtn.Checked = Globals.ThisAddIn.helpTaskPane.Visible; }

運行效果圖為:

      

四、自定義上下文菜單

 看完上面兩部分的實現之后,我在學習的過程中又想——能不能通過右鍵菜單來顯示/隱藏任務窗體呢? 對於這點VSTO也是可以做到的,我們只需要添加CommandBarButton對象(當我們右鍵一個單元格(即為Cell)的時候,我們可以看到一上下文菜單,菜單內所有控件(不管是按鈕還是排序這樣的菜單控件)),然后設置該對象的屬性和添加一個Click事件,主要代碼如下:

 // 添加一個自定義按鈕到單元格上下文菜單中
            contextMenu =Application.CommandBars["Cell"];
            CommandBarButton commandBarbtn = (CommandBarButton)contextMenu.Controls.Add(MsoControlType.msoControlButton, Before: 1);
            commandBarbtn.Tag = "Help_Tag";
            commandBarbtn.Caption = "查看幫助";
            commandBarbtn.FaceId = 49;
            commandBarbtn.Click+=new _CommandBarButtonEvents_ClickEventHandler(commandBarbtn_Click);  

運行效果為(這樣我們右鍵Cell的時候就會多出一個我們自己定義的 ”查看幫助“按鈕):

五、小結

  到這里本專題的內容就介紹完了,本專題主要介紹如何為Excel創建一個自定義的任務窗體、Ribbon和上下文菜單,對於Word和Outlook這部分的內容我就不重復介紹,創建方式和Excel的創建方式很類似。在下一個專題中我將給大家介紹下如何創建Word解決方案。

本專題所有源碼:http://files.cnblogs.com/zhili/ExcelHelpTaskPane.zip 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM