共用方式為


在 Office 文件中保存動態控制項

更新: 2008 年 7 月

適用於

本主題中的資訊僅適用於指定的 Visual Studio Tools for Office 專案和 Microsoft Office 版本。

文件層級專案

  • Excel 2003

  • Excel 2007

  • Word 2003

  • Word 2007

應用程式層級專案

  • Excel 2007

  • Word 2007

如需詳細資訊,請參閱依應用程式和專案類型提供的功能

儲存和關閉文件或活頁簿時,並不會保存在執行階段加入的控制項。實際的行為會隨著主控制項和 Windows Form 控制項而不同。對於這兩種情況,當使用者重新開啟文件時,您都可以在方案中加入程式碼重新建立控制項。

在執行階段加入至文件的控制項稱為「動態控制項」(Dynamic Control)。如需動態控制項的詳細資訊,請參閱在執行階段將控制項加入至 Office 文件

在文件中保存主控制項

當儲存並關閉文件時,所有動態的主控制項都會從文件移除。只會留下基礎原生的 Office 物件。例如,Microsoft.Office.Tools.Excel.ListObject 主控制項會變成 Microsoft.Office.Interop.Excel.ListObject。原生的 Office 物件不會連接到主控制項事件,而且也沒有主控制項的資料繫結功能。

下表列出針對每種主控制項型別而留在文件中的原生 Office 物件。

主控制項型別

原生 Office 物件型別

Microsoft.Office.Tools.Excel.Chart

Microsoft.Office.Interop.Excel.Chart

Microsoft.Office.Tools.Excel.ListObject

Microsoft.Office.Interop.Excel.ListObject

Microsoft.Office.Tools.Excel.NamedRange

Microsoft.Office.Interop.Excel.Range

Microsoft.Office.Tools.Word.Bookmark

Microsoft.Office.Interop.Word.Bookmark

Microsoft.Office.Tools.Word.BuildingBlockGalleryContentControl

Microsoft.Office.Tools.Word.ComboBoxContentControl

Microsoft.Office.Tools.Word.ContentControl

Microsoft.Office.Tools.Word.DatePickerContentControl

Microsoft.Office.Tools.Word.DropDownListContentControl

Microsoft.Office.Tools.Word.GroupContentControl

Microsoft.Office.Tools.Word.PictureContentControl

Microsoft.Office.Tools.Word.PlainTextContentControl

Microsoft.Office.Tools.Word.RichTextContentControl

Microsoft.Office.Interop.Word.ContentControl

在開啟文件時重新建立動態主控制項

您可以在每次使用者開啟文件時,重新建立動態主控制項來取代現有的原生 (Native) 控制項。以這種方式在開啟文件時建立主控制項,即可模擬使用者預期的情況。

若要重新建立 Word 的主控制項,或 Excel 的 Microsoft.Office.Tools.Excel.NamedRangeMicrosoft.Office.Tools.Excel.ListObject 主控制項,請使用具有原生 Office 物件之參數的 Microsoft.Office.Tools.Excel.ControlCollectionMicrosoft.Office.Tools.Word.ControlCollection 類別的 Add<control class> 方法。

例如,如果您要在開啟文件時,從現有的原生 Microsoft.Office.Interop.Excel.ListObject 建立 Microsoft.Office.Tools.Excel.ListObject 主控制項,請使用 AddListObject(ListObject) 方法並傳入現有的 Microsoft.Office.Interop.Excel.ListObject。在下列程式碼範例中,會以 Excel 2007 文件層級專案進行這項示範。程式碼會根據 Sheet1 類別中現有的 Microsoft.Office.Interop.Excel.ListObject (名為 MyListObject) 重新建立動態 Microsoft.Office.Tools.Excel.ListObject

Private vstoListObject As Microsoft.Office.Tools.Excel.ListObject
Private Const DISP_E_BADINDEX As Integer = CInt(&H8002000B)

Private Sub Sheet1_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
    Dim nativeListObject As Excel.ListObject = Nothing

    Try
        nativeListObject = Me.ListObjects("MyListObject")
    Catch ex As System.Runtime.InteropServices.COMException
        ' "MyListObject" does not exist.
        If ex.ErrorCode <> DISP_E_BADINDEX Then
            Throw
        End If
    End Try

    If nativeListObject IsNot Nothing Then
        vstoListObject = Me.Controls.AddListObject(nativeListObject)
    End If
End Sub
private Microsoft.Office.Tools.Excel.ListObject vstoListObject;
private const int DISP_E_BADINDEX = unchecked((int)0x8002000B);

private void Sheet1_Startup(object sender, System.EventArgs e)
{
    Excel.ListObject nativeListObject = null;

    try
    {
        nativeListObject = this.ListObjects.get_Item("MyListObject");
    }
    catch (System.Runtime.InteropServices.COMException ex)
    {
        // "MyListObject" does not exist.
        if (ex.ErrorCode != DISP_E_BADINDEX)
            throw;
    }

    if (nativeListObject != null)
    {
        vstoListObject = this.Controls.AddListObject(nativeListObject);
    }
}

如需示範動態控制項的文件層級範例,請參閱 Excel 動態控制項範例Word 動態控制項範例

如需示範動態控制項的應用程式層級範例,請參閱 Excel 增益集動態控制項範例Word 增益集動態控制項範例

在 Excel 2003 和 SP1 前的 Excel 2007 專案中重新建立 ListObjects

AddListObject(ListObject) 是 Visual Studio 2008 Service Pack 1 (SP1) 中 Excel 2007 專案的新方法。如果您目前使用的是 Excel 2007 專案,並且尚未安裝 SP1,或者您目前使用的是 Excel 2003 專案,則無法使用這個方法來重新建立動態 Microsoft.Office.Tools.Excel.ListObject

因此,您必須先刪除原生 Microsoft.Office.Interop.Excel.ListObject,然後使用 AddListObject(Range, String) 方法重新建立動態 Microsoft.Office.Tools.Excel.ListObject。如需此做法的範例程式碼,請參閱 Excel 動態控制項範例

如果沒有先刪除原生 Microsoft.Office.Interop.Excel.ListObject,則您將會在嘗試重新建立 Microsoft.Office.Tools.Excel.ListObject 時收到 COMException,因為 Excel 不允許您建立重疊清單物件。

重新建立圖表

若要重新建立 Microsoft.Office.Tools.Excel.Chart 主控制項,您必須先刪除原生 Microsoft.Office.Interop.Excel.Chart,然後使用 AddChart(Range, String)AddChart(Double, Double, Double, Double, String) 方法重新建立 Microsoft.Office.Tools.Excel.Chart。其中沒有 Add<control class> 方法可讓您根據現有的 Microsoft.Office.Interop.Excel.Chart 建立新的 Microsoft.Office.Tools.Excel.Chart

如果沒有先刪除原生 Microsoft.Office.Interop.Excel.Chart,則您將會在重新建立 Microsoft.Office.Tools.Excel.Chart 時,建立第二個重複的圖表。

在文件上保存 Windows Form 控制項

當儲存並關閉文件時,Visual Studio Tools for Office 執行階段會自動從文件中移除所有動態建立的 Windows Form 控制項。然而,這項行為會隨著文件層級和應用程式層級專案而不同。

在文件層級自訂中,控制項和其基礎 ActiveX 包裝函式 (這是用來在文件上裝載控制項的) 是在下次開啟文件時移除的。而且不會有指示說明曾經有這些控制項存在。

在應用程式層級的增益集中會移除控制項,但 ActiveX 包裝函式會保留在文件中。當使用者下次開啟文件時,就會看到 ActiveX 包裝函式。在 Excel 中,ActiveX 包裝函式會顯示控制項的影像,就如同上次儲存文件時的顯示方式。在 Word 中,除非使用者按一下 ActiveX 包裝函式,否則並不會顯示包裝函式,而這種情況下會顯示虛線表示控制項的框線。您可以使用許多方式移除 ActiveX 包裝函式。如需詳細資訊,請參閱移除增益集中的 ActiveX 包裝函式。

在開啟文件時重新建立 Windows Form 控制項

您可以在使用者重新開啟文件時,重新建立刪除的 Windows Form 控制項。若要進行這項工作,您的方案必須執行下列工作:

  1. 在儲存或關閉文件時,儲存控制項的大小、位置和狀態的資訊。在文件層級自訂中,您可以將這項資料儲存在文件的資料快取中。在應用程式層級的增益集中,您可以將這項資料儲存在文件的自訂 XML 組件中。

  2. 在會於文件開啟時引發的事件中重新建立控制項。在文件層級專案中,您可以在 Sheetn_Startup 或 ThisDocument_Startup 事件處理常式中進行這項作業。在應用程式層級專案中,您可以在 WorkbookOpenDocumentOpen 事件的事件處理常式中進行這項作業。

如需示範動態控制項的文件層級範例,請參閱 Excel 動態控制項範例Word 動態控制項範例

如需應用程式層級的範例,請參閱 Excel 增益集動態控制項範例Word 增益集動態控制項範例

移除增益集中的 ActiveX 包裝函式

使用增益集將動態 Windows Form 控制項加入文件中時,您可以使用下列方式,防止在下次開啟文件時出現控制項的 ActiveX 包裝函式。

在文件開啟時移除 ActiveX 包裝函式

若要移除所有的 ActiveX 包裝函式,請呼叫用於表示最近開啟過文件的 Microsoft.Office.Interop.Word.DocumentMicrosoft.Office.Interop.Excel.Workbook 的 GetVstoObject 方法。例如,若要從 Word 文件移除所有 ActiveX 包裝函式,您可以呼叫 Document 物件的 GetVstoObject 方法 (此物件會傳遞給 DocumentOpen 事件的事件處理常式)。

當您確定只會在有安裝增益集的電腦上開啟文件時,這個程序就非常好用。如果文件可能會傳遞給沒有安裝增益集的其他使用者,請改為考慮在關閉文件前先移除控制項。

下列程式碼範例示範如何在開啟文件時呼叫 GetVstoObject 方法。

Private Sub Application_DocumentOpen_ClearActiveXWrappers( _
    ByVal Doc As Word.Document) Handles Application.DocumentOpen
    Dim vstoDocument As Microsoft.Office.Tools.Word.Document = Doc.GetVstoObject()
End Sub
private void Application_DocumentOpen_ClearActiveXWrappers(Word.Document Doc)
{
    Microsoft.Office.Tools.Word.Document vstoDocument = Doc.GetVstoObject();
}

雖然 GetVstoObject 方法主要是用來在執行階段產生新的主項目,但針對特定文件首次呼叫這個方法時,方法也會清除文件中的所有 ActiveX 包裝函式。如需如何使用 GetVstoObject 方法的詳細資訊,請參閱在應用程式層級增益集的執行階段中擴充 Word 文件和 Excel 活頁簿

請注意,如果增益集會在文件開啟時建立動態控制項,那麼增益集即已經將呼叫 GetVstoObject 方法做為建立控制項的程序的一部分。在這種情況下,不需要加入個別的 GetVstoObject 方法呼叫來移除 ActiveX 包裝函式。

在關閉文件前移除動態控制項

增益集可以在關閉文件前,明確移除文件中的每個動態控制項。當文件可能會傳遞給沒有安裝增益集的其他使用者時,這個程序就非常好用。

下列程式碼範例將示範如何在關閉文件時,移除 Word 文件中的所有 Windows Form 控制項。

Private Sub Application_DocumentBeforeClose(ByVal Doc As Word.Document, _
    ByRef Cancel As Boolean) Handles Application.DocumentBeforeClose

    If Doc.HasVstoObject() Then
        Dim vstoDocument As Microsoft.Office.Tools.Word.Document = _
            Doc.GetVstoObject()
        Dim controlsToRemove As System.Collections.ArrayList = _
            New System.Collections.ArrayList()

        ' Get all of the Windows Forms controls.
        For Each control As Object In vstoDocument.Controls
            If TypeOf control Is System.Windows.Forms.Control Then
                controlsToRemove.Add(control)
            End If
        Next

        ' Remove all of the Windows Forms controls from the document.
        For Each control As Object In controlsToRemove
            vstoDocument.Controls.Remove(control)
        Next
    End If
End Sub
void Application_DocumentBeforeClose(Word.Document Doc, ref bool Cancel)
{
    if (Doc.HasVstoObject())
    {
        Microsoft.Office.Tools.Word.Document vstoDocument = Doc.GetVstoObject();
        System.Collections.ArrayList controlsToRemove = 
            new System.Collections.ArrayList();

        // Get all of the Windows Forms controls.
        foreach (object control in vstoDocument.Controls)
        {
            if (control is System.Windows.Forms.Control)
            {
                controlsToRemove.Add(control);
            }
        }

        // Remove all of the Windows Forms controls from the document.
        foreach (object control in controlsToRemove)
        {
            vstoDocument.Controls.Remove(control);
        }
    }
}

請參閱

工作

Excel 動態控制項範例

Word 動態控制項範例

Excel 增益集動態控制項範例

Word 增益集動態控制項範例

概念

在執行階段將控制項加入至 Office 文件

主控制項的 Helper 方法

Windows Form 控制項的 Helper 方法

變更記錄

日期

記錄

原因

2008 年 7 月

加入應用程式層級增益集中保存動態控制項的相關資訊。

SP1 功能變更。