我们为 Word 2010 开发了一个 Word VSTO 加载项,通过VSTOContrib提供 CustomTaskPanes 和 MVVM 支持。
升级到 Word 2016/2019 后,我们的 CustomTaskPanes 随机显示,无需用户进行任何操作。似乎 Word 会注意到何时使用 CustomTaskPane 并希望下次自动(重新)打开它。
例如,在打开一个新的/现有的文档时会打开一个 CustomTaskPane。不会那么糟糕,如果它不会出现故障(打开,关闭,打开,关闭,...)直到它关闭或保持打开状态。如果 CustomTaskPane 保持打开状态,则它不可用,因为它没有我们的加载项加载的 DataContext。
ThisAddIn 中的此代码创建/删除 CustomTaskPanes:
public CustomTaskPane AddTaskPane(UserControl userControl, string title, Window owner)
{
return CustomTaskPanes.Add(userControl, title, owner);
}
public void RemoveTaskPane(CustomTaskPane taskPane)
{
if (taskPane == null)
return;
CustomTaskPanes.Remove(taskPane);
}
RibbonViewModel (ViewModel per Document/Window) 像这样调用代码。_addInHelper
具有用于创建/删除 CustomTaskPane 以到达ThisAddIn
代码并通过回调返回 CustomTaskPane 实例的事件。它还使用 IoC 容器来解析视图"CustomTaskPaneView"
。
// Gets called when a new Window opens or a new Document is opened
public override void Intialize(Document document)
{
// ...
CreateCustomTaskPane();
// ...
}
private void CreateCustomTaskPane()
{
if (_customTaskPane != null)
return;
_addInHelper.AddTaskPane("CustomTaskPaneView", "Custom headline", CurrentWindow, result =>
{
_customTaskPane = result;
});
if (_customTaskPane == null)
{
_log.Error(...);
return;
}
_customTaskPane.DockPositionRestrict = MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoHorizontal;
_customTaskPane.Width = Settings.Default.TaskPaneWidth;
_customTaskPane.DockPosition = Settings.Default.TaskPanePosition;
// TaskPane height and width are saved seperately for DockPositionFloating
if (_customTaskPane.DockPosition != MsoCTPDockPosition.msoCTPDockPositionFloating)
{
// Set height and width for DockPositionFloating.
// If the user drags the TaskPane to Floating, it will have the correct size.
var oldDockPosition = _customTaskPane.DockPosition;
_customTaskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionFloating;
_customTaskPane.Height = Settings.Default.TaskPaneHeight;
_customTaskPane.Width = Settings.Default.TaskPaneWidth;
_customTaskPane.DockPosition = oldDockPosition;
}
else
{
_customTaskPane.Height = Settings.Default.TaskPaneHeight;
_customTaskPane.Width = Settings.Default.TaskPaneWidth;
}
// Saving/updating settings in these
_customTaskPane.VisibleChanged += ContentControlsTaskPane_OnVisibleChanged;
_customTaskPane.DockPositionChanged += ContentControlsTaskPane_OnDockPositionChanged;
}
关闭窗口/文档时,调用此代码:
public override void Cleanup()
{
if (_customTaskPane != null)
{
SaveCustomTaskPaneProperties();
_contentControlsTaskPane.VisibleChanged -= ContentControlsTaskPane_OnVisibleChanged;
_contentControlsTaskPane.DockPositionChanged -= ContentControlsTaskPane_OnDockPositionChanged;
// Checks if the COM Object was cleaned up already
if (!_contentControlsTaskPane.IsDisposed())
{
// Tried to manually close the CustomTaskPane, but didn't help either
if (_contentControlsTaskPane.Visible)
_contentControlsTaskPane.Visible = false;
// Cleanup the CustomTaskPane ViewModel instance
var taskPaneViewModel = _contentControlsTaskPane.GetViewModel();
taskPaneViewModel?.Dispose();
_addInHelper.RemoveTaskPane(_contentControlsTaskPane);
}
}
}
这仅在使用 Word 2016 和 2019(我们不使用 2013)时发生,而在 Word 2010 中根本不会发生。出于测试目的将 VSTO 项目升级到 VSTO 插件 2013 和 2016 后,它并没有变得更好。
我没有找到任何可能导致此问题的 Word 选项。知道这可能导致什么以及如何解决这个问题/获得解决方法吗?
编辑
这是更新的代码示例WordTaskPanesBug
重现步骤:
- 启动 Word/运行项目
- 点击“打开”按钮
- 点击“新建文档”按钮
- 单击“新建文档”按钮,TaskPane 被打开(但这次不会出现故障)
在示例项目中关闭文档时,CustomTaskPane 也会出现故障,但在我们的实际项目中却没有。