Ответ 1
Используйте hwnd (Globals.ThisAddIn.Application.Hwnd), чтобы идентифицировать окно Excel. Это будет хорошо работать как для Office2013 (который использует подход SDI), так и для старых версий Office, которые используют окна MDI. Вот класс, который вы можете использовать для этого:
public class TaskPaneManager
{
static Dictionary<string, CustomTaskPane> _createdPanes = new Dictionary<string, CustomTaskPane>();
/// <summary>
/// Gets the taskpane by name (if exists for current excel window then returns existing instance, otherwise uses taskPaneCreatorFunc to create one).
/// </summary>
/// <param name="taskPaneId">Some string to identify the taskpane</param>
/// <param name="taskPaneTitle">Display title of the taskpane</param>
/// <param name="taskPaneCreatorFunc">The function that will construct the taskpane if one does not already exist in the current Excel window.</param>
public static CustomTaskPane GetTaskPane(string taskPaneId, string taskPaneTitle, Func<UserControl> taskPaneCreatorFunc)
{
string key = string.Format("{0}({1})", taskPaneId, Globals.ThisAddIn.Application.Hwnd);
if (!_createdPanes.ContainsKey(key))
{
var pane = Globals.ThisAddIn.CustomTaskPanes.Add(taskPaneCreatorFunc(), taskPaneTitle);
_createdPanes[key] = pane;
}
return _createdPanes[key];
}
}
Здесь я фактически комбинирую окно Excel hwnd и некоторый произвольный строковый идентификатор для идентификации панели задач. Идея состоит в том, чтобы поддерживать несколько задач в одном и том же добавлении.
Вот пример того, как использовать его с ленты:
private void button1_Click(object sender, RibbonControlEventArgs e)
{
var taskpane = TaskPaneManager.GetTaskPane("A", "Task pane type A", () => new UserControl1());
taskpane.Visible = !taskpane.Visible;
}
private void button2_Click(object sender, RibbonControlEventArgs e)
{
var taskpane = TaskPaneManager.GetTaskPane("B", "Task pane type B", () => new UserControl2());
taskpane.Visible = !taskpane.Visible;
}
Если вы открываете несколько книг в Excel, оба окна Excel будут иметь собственные taspaneA и taskpaneB.