Compartilhar via


Persistência de controles dinâmicos em documentos do Office

Os controles são adicionados em tempo de execução não são mantidos quando o documento ou pasta de trabalho é salvo e fechada. O comportamento exato é diferente para os controles de host e os controles Windows Forms. Em ambos os casos, você pode adicionar código à sua solução recriar controles quando o usuário reabre o documento.

Controles que você adicionar a documentos em tempo de execução são chamados de controles dinâmicos. Para obter mais informações sobre controles dinâmicos, consulte Adicionar controles a documentos do Office em tempo de execução.

Aplicável a: As informações neste tópico se aplicam a projetos de nível de documento e projetos de nível de aplicativo para os seguintes aplicativos: Excel 2007 e Excel 2010; Word 2007 e Word 2010. Para obter mais informações, consulte Recursos disponíveis pelo aplicativo do Office e o tipo de projeto.

Controles de Host de persistência no documento

Quando um documento é salvo e, em seguida, fechado, todos os controles de host dinâmico são removidos do documento. Somente nativos Office objetos subjacentes permanecem atrás. Por exemplo, um Microsoft.Office.Tools.Excel.ListObject o controle de host se torna um Microsoft.Office.Interop.Excel.ListObject. Objetos nativos do Office não estiver conectados a eventos de controle de host, e eles não têm a funcionalidade de ligação de dados do controle de host.

A tabela a seguir lista o objeto nativo do Office que é deixado para trás em um documento para cada tipo de controle de host.

Tipo de controle de host

Tipo de objeto do Office nativo

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

Recriando a controles de Host Dinâmico quando documentos são abertos.

Você pode recriar os controles de host dinâmico no lugar dos controles nativos existentes sempre que um usuário abre o documento. Criando controles de host dessa maneira, quando um documento é aberto simula a experiência que os usuários podem esperar.

Para recriar um controle de host para o Word, ou um Microsoft.Office.Tools.Excel.NamedRange ou Microsoft.Office.Tools.Excel.ListObject hospedem o controle para o Excel, use um Add<a classe de controle> método de um Microsoft.Office.Tools.Excel.ControlCollection ou Microsoft.Office.Tools.Word.ControlCollection objeto. Use um método que possui um parâmetro para o objeto nativo do Office.

Por exemplo, se você deseja criar um Microsoft.Office.Tools.Excel.ListObject o controle de host de um existente nativo Microsoft.Office.Interop.Excel.ListObject quando o documento for aberto, use o AddListObject(ListObject) método e passar a existente Microsoft.Office.Interop.Excel.ListObject. O exemplo de código a seguir demonstra isso em um projeto de nível de documento do Excel. O código recria um dinâmico Microsoft.Office.Tools.Excel.ListObject que se baseia em uma existente Microsoft.Office.Interop.Excel.ListObject chamado MyListObject na Sheet1 classe.

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);
    }
}

Recriando a gráficos

Para recriar um Microsoft.Office.Tools.Excel.Chart hospedar o controle, você deve primeiro excluir o nativo Microsoft.Office.Interop.Excel.Charte então recrie a Microsoft.Office.Tools.Excel.Chart usando o AddChart(Range, String) ou AddChart(Double, Double, Double, Double, String) método. Não há nenhum Add<a classe de controle> método que permite que você crie uma nova Microsoft.Office.Tools.Excel.Chart com base em uma Microsoft.Office.Interop.Excel.Chart.

Se você não excluir primeiro nativa Microsoft.Office.Interop.Excel.Chart, e em seguida, você criará um gráfico de segundo, duplicado quando você recriar o Microsoft.Office.Tools.Excel.Chart.

Persistência dos controles Windows Forms em documentos

Quando um documento é salvo e, em seguida, fechado, o Visual Studio Tools for Office runtime remove automaticamente todos os controles do Windows Forms criados dinamicamente a partir do documento. No entanto, o comportamento é diferente para projetos de nível de aplicativo e de documento.

No nível do documento personalizações, os controles e seus invólucros subjacentes do ActiveX (que são usados para hospedar os controles no documento) são removidos na próxima vez em que o documento for aberto. Não há nenhuma indicação de que os controles foram nunca lá.

No nível do aplicativo add-ins, os controles são removidos, mas os invólucros de ActiveX permanecem no documento. Na próxima vez em que o usuário abre o documento, os invólucros de ActiveX são visíveis. No Excel, os wrappers ActiveX exibem imagens dos controles, como eles apareciam na última vez em que o documento foi salvo. No Word, os wrappers ActiveX invisíveis, a menos que o usuário clica sobre eles, caso em que elas exibem uma linha pontilhada que representa a borda dos controles. Há várias maneiras que você pode remover os invólucros de ActiveX. Para obter mais informações, consulte Removendo invólucros de ActiveX um Add - in.

Recriar controles Windows Forms quando documentos são abertos.

Você pode recriar os controles do Windows Forms excluídos quando o usuário reabre o documento. Para fazer isso, a sua solução deve executar as seguintes tarefas:

  1. Armazenar informações sobre o tamanho, a localização e o estado dos controles quando o documento for salvo ou fechado. Uma personalização de nível de documento, você pode salvar esses dados para o cache de dados no documento. Em um suplemento do nível de aplicativo, você pode salvar esses dados para uma parte XML personalizada no documento.

  2. Recrie os controles em um evento que é disparado quando o documento for aberto. Em projetos de nível de documento, você pode fazer isso Sheetn_Startup ou ThisDocument_Startup manipuladores de evento. Em projetos de nível de aplicativo, você pode fazer nesse evento manipuladores para o WorkbookOpen ou DocumentOpen eventos.

Removendo os invólucros de ActiveX em um suplemento

Quando você adiciona controles dinâmicos do Windows Forms a documentos usando um suplemento, você pode impedir os invólucros de ActiveX para os controles que aparecem no documento, na próxima vez em que ele é aberto das maneiras a seguir.

Removendo os invólucros de ActiveX quando o documento é aberto.

Para remover todos os invólucros de ActiveX, chame o GetVstoObject método para gerar um item de host para o Microsoft.Office.Interop.Word.Document ou Microsoft.Office.Interop.Excel.Workbook que representa o documento aberto recentemente. Por exemplo, para remover todos os invólucros de ActiveX de um documento do Word, você pode chamar o GetVstoObject método para gerar um item de host para o Document o objeto que é passado para o manipulador de eventos para o DocumentOpen evento.

Esse procedimento é útil quando você sabe que o documento será aberto somente em computadores que possuem o suplemento instalado. Se o documento pode ser passado para outros usuários que não possuem o add-in instalado, considere a remoção dos controles antes de fechar o documento em vez disso.

O exemplo de código a seguir demonstra como chamar o GetVstoObject método quando o documento for aberto.

Private Sub Application_DocumentOpen_ClearActiveXWrappers( _
    ByVal Doc As Word.Document) Handles Application.DocumentOpen

    ' Use the following line of code in projects that target the .NET Framework 4.
    Dim vstoDocument As Document = Globals.Factory.GetVstoObject(Doc)

    ' In projects that target the .NET Framework 3.5, use the following line of code.
    ' Dim vstoDocument As Microsoft.Office.Tools.Word.Document = Doc.GetVstoObject()
End Sub
private void Application_DocumentOpen_ClearActiveXWrappers(Word.Document Doc)
{
    // Use the following line of code in projects that target the .NET Framework 4.
    Microsoft.Office.Tools.Word.Document vstoDocument = Globals.Factory.GetVstoObject(Doc);

    // In projects that target the .NET Framework 3.5, use the following line of code.
    // Microsoft.Office.Tools.Word.Document vstoDocument = Doc.GetVstoObject();
}

Embora o GetVstoObject método é usado principalmente para gerar um novo item de host em tempo de execução, esse método também limpa todos os invólucros de ActiveX do documento na primeira vez que ele é chamado para um documento específico. Para obter mais informações sobre como usar o GetVstoObject método, consulte Estendendo os documentos do Word e pastas de trabalho do Excel em suplementos de nível de aplicativo em tempo de execução.

Observe que se o add-in cria controles dinâmicos quando o documento for aberto, o add-in já chamará o GetVstoObject o método como parte do processo para criar controles. Você não precisará adicionar uma chamada separada para o GetVstoObject método para remover os wrappers ActiveX neste cenário.

Removendo os controles dinâmicos antes do documento é fechado.

O add-in pode remover explicitamente cada controle dinâmico do documento antes do documento é fechado. Esse procedimento é útil para documentos que podem ser passados para outros usuários que não possuem o suplemento instalado.

O exemplo de código a seguir demonstra como remover todos os controles Windows Forms a partir de um documento do Word quando o documento é fechado.

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

    ' Use the following line of code in projects that target the .NET Framework 4.
    Dim isExtended As Boolean = Globals.Factory.HasVstoObject(Doc)

    ' In projects that target the .NET Framework 3.5, use the following line of code.
    ' Dim isExtended As Boolean = Doc.HasVstoObject()

    If isExtended Then
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim vstoDocument As Document = Globals.Factory.GetVstoObject(Doc)

        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim vstoDocument As 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)
{
    // Use the following line of code in projects that target the .NET Framework 4.
    bool isExtended = Globals.Factory.HasVstoObject(Doc);

    // In projects that target the .NET Framework 3.5, use the following line of code.
    // bool isExtended = Doc.HasVstoObject();

    if (isExtended)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Microsoft.Office.Tools.Word.Document vstoDocument = Globals.Factory.GetVstoObject(Doc);

        // In projects that target the .NET Framework 3.5, use the following line of code.
        // 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);
        }
    }
}

Consulte também

Conceitos

Adicionar controles a documentos do Office em tempo de execução

Métodos auxiliares para controles de Host

Métodos auxiliares para controles Windows Forms