Сохранение динамических элементов управления в документах Office
Элементы управления, добавленные во время выполнения, не сохраняются при сохранении и закрытии документа или книги.Поведение ведущих элементов управления и элементов управления Windows Forms различается.В обоих случаях можно добавить в решение код, который будет пересоздавать элементы управления при повторном открытии документа.
Элементы управления, добавляемые в документ во время выполнения, называются динамическими элементами управления.Дополнительные сведения о динамических элементах управления см. в разделе Добавление элементов управления в документы Office во время выполнения.
Применение. Сведения этого раздела применяются к проектам уровня документа и уровня приложения для следующих приложений: Excel 2013 и Excel 2010; Word 2013 и Word 2010. Дополнительные сведения см. в разделе Доступность функций по типам приложений Office и проектов.
Сохранение элементов управления ведущего приложения в документе
Когда документ сохраняется, а затем закрывается, все динамические ведущие элементы управления Windows Forms удаляются из этого документа.Остаются только собственные базовые объекты Office.Например, элемент управления Microsoft.Office.Tools.Excel.ListObject становится элементом Microsoft.Office.Interop.Excel.ListObject.Собственные объекты Office не связаны с событиями ведущих элементов управления и не имеют функции привязки данных, как в случае с ведущими элементами управления.
В следующей таблице перечислены собственные объекты Office, которые остаются в документе, для каждого типа ведущих элементов управления.
Повторное создание динамических ведущих элементов управления при открытии документов
Динамический ведущий элемент управления можно воссоздавать на месте существующего собственного элемента управления при каждом открытии документа.Такой способ создания ведущих элементов управления при открытии документа имитирует ожидаемый пользователем процесс.
Чтобы повторно создать элемент управления ведущего приложения для Word или элемент управления ведущего приложения Microsoft.Office.Tools.Excel.NamedRange или Microsoft.Office.Tools.Excel.ListObject для Excel, используйте метод Add<ведущий класс> объекта Microsoft.Office.Tools.Excel.ControlCollection или Microsoft.Office.Tools.Word.ControlCollection.Используйте метод, имеющий параметр для собственного объекта Office.
Например, чтобы создать ведущий элемент управления Microsoft.Office.Tools.Excel.ListObject на основе существующего собственного объекта Microsoft.Office.Interop.Excel.ListObject при открытии документа, следует использовать метод AddListObject(ListObject) и передать ему существующий элемент управления Microsoft.Office.Interop.Excel.ListObject.В следующем примере кода описываемая выше процедура демонстрируется в проекте уровня документа для Excel.Код повторно создает динамический объект Microsoft.Office.Tools.Excel.ListObject, основанный на существующем объекте Microsoft.Office.Interop.Excel.ListObject с именем MyListObject в классе Sheet1.
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);
}
}
Воссоздание графиков
Для воссоздания графика Microsoft.Office.Tools.Excel.Chart сначала следует удалить собственный объект Microsoft.Office.Interop.Excel.Chart, а затем воссоздать график Microsoft.Office.Tools.Excel.Chart с помощью метода AddChart(Range, String) or AddChart(Double, Double, Double, Double, String).Метода Add<класс элемента управления>, который позволит создать новый графикMicrosoft.Office.Tools.Excel.Chart на основе существующего графика Microsoft.Office.Interop.Excel.Chart, не существует.
Если собственный объект Microsoft.Office.Interop.Excel.Chart не будет предварительно удален, следовательно, при повторном создании графикаMicrosoft.Office.Tools.Excel.Chart будет создан второй, дублирующий график.
Сохранение элементов управления Windows Forms в документах
Когда документ сохраняется, а затем закрывается, среда Visual Studio Tools for Office (cреда выполнения) автоматически удаляет все динамически созданные элементы управления Windows Forms из документа.В то же время поведение настроек уровня документа и проектов уровня приложения различается.
В настройках уровня документа элементы управления и их базовые оболочки ActiveX (которые используются для размещения элементов управления в документе) удаляются при следующем открытии документа.Указания на то, что в этом месте были элементы управления, отсутствуют.
В надстройках на уровне приложения элементы управления удаляются, однако оболочки ActiveX остаются в документе.Оболочки ActiveX видимы и при следующем открытии документа.В Excel оболочки ActiveX отображают изображения внешнего вида элементов управления на момент последнего сохранения документа.В Word оболочки ActiveX невидимы до тех пор, пока пользователь не щелкнет на них. В этом случае отображается пунктирная линии, представляющая границу элементов управления.Существует несколько способов удаления оболочек ActiveX.Дополнительные сведения см. в разделе Удаление оболочек ActiveX в надстройке.
Повторное создание элементов управления Windows Forms при открытии документов
При повторном открытии документа можно воссоздавать удаленные элементы управления Windows Forms.Для этого решение должно выполнить следующие задачи:
Хранить данные о размере, местоположении и состоянии элементов управления при сохранении и закрытии документа.В настройке уровня документа эти данные можно сохранить в кэш данных документа.В надстройке уровня приложения эти данные можно сохранить в пользовательской XML-части документа.
Воссоздать элементы управления в событии, которое вызывается при открытии документа.В проектах уровня документа можно сделать это в обработчике событий Sheetn_Startup или ThisDocument_Startup.В проектах уровня приложения это можно сделать в обработчиках событий для событий WorkbookOpen или DocumentOpen.
Удаление оболочек ActiveX в надстройке
При добавлении динамических элементов управления Windows Forms в документы с помощью надстройки можно избежать появления в документе оболочек ActiveX для элементов управления при повторном открытии документа.
Удаление оболочки ActiveX при открытии документа
Чтобы удалить все оболочки ActiveX, необходимо вызвать метод GetVstoObject для создания ведущего элемента для объекта Microsoft.Office.Interop.Word.Document или Microsoft.Office.Interop.Excel.Workbook, представляющих вновь открытый документ.Например, чтобы удалить все оболочки ActiveX из документа Word, можно вызвать метод GetVstoObject для создания ведущего элемента объекта Document, передаваемого в обработчик событий для события DocumentOpen.
Данная процедура имеет смысл, если известно, что документ будет открываться только на компьютерах с установленной надстройкой.Если документ будет передаваться другим пользователям, на компьютерах которых не установлена надстройка, рекомендуется вместо этого удалить элементы управления перед закрытием документа.
Следующий пример кода демонстрирует вызов метода GetVstoObject при открытии документа.
Private Sub Application_DocumentOpen_ClearActiveXWrappers( _
ByVal Doc As Word.Document) Handles Application.DocumentOpen
Dim vstoDocument As Document = Globals.Factory.GetVstoObject(Doc)
End Sub
private void Application_DocumentOpen_ClearActiveXWrappers(Word.Document Doc)
{
Microsoft.Office.Tools.Word.Document vstoDocument = Globals.Factory.GetVstoObject(Doc);
}
Хотя метод GetVstoObject используется в основном для создания новых ведущих элементов управления во время выполнения, с помощью данного метода можно также удалить все оболочки ActiveX из документа при первом вызове метода для конкретного документа.Дополнительные сведения об использовании метода GetVstoObject, см. в разделе Расширение документов Word и книг Excel в надстройках уровня приложения во время выполнения.
Обратите внимание, что в случае, если надстройка создает динамические элементы управления при открытии документа, она также вызовет метод GetVstoObject в ходе процесса создания элементов управления.В рамках данного скрипта необязательно добавлять отдельный вызов метода GetVstoObject чтобы удалить все оболочки ActiveX.
Удаление динамических элементов управления до закрытия документа
Надстройка может явным образом удалить все динамические элементы управления из документа перед его закрытием.Данная процедура имеет смысл в том случае, если документы заведомо будут передаваться пользователям, на компьютерах которых не установлена надстройка.
Следующий пример кода демонстрирует удаление всех элементов управления Windows Forms из документа Word перед его закрытием.
Private Sub Application_DocumentBeforeClose(ByVal Doc As Word.Document, _
ByRef Cancel As Boolean) Handles Application.DocumentBeforeClose
Dim isExtended As Boolean = Globals.Factory.HasVstoObject(Doc)
If isExtended Then
Dim vstoDocument As Document = Globals.Factory.GetVstoObject(Doc)
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)
{
bool isExtended = Globals.Factory.HasVstoObject(Doc);
if (isExtended)
{
Microsoft.Office.Tools.Word.Document vstoDocument = Globals.Factory.GetVstoObject(Doc);
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);
}
}
}
См. также
Основные понятия
Добавление элементов управления в документы Office во время выполнения