Я пишу VSTO уровня приложения Excel.Но есть кое-что, чего я не понимаю.Созданная мной настраиваемая вкладка ленты доступна на уровне приложения, то есть для всех открытых рабочих книг.
Я создал вкладку ленты с помощью Конструктор ленты и вызываю ее экземпляр с помощью функции.setRibbonControlState
в файле ThisAddIn.cs
.Функция вызывается тремя событиями, которые я обрабатываю из ThisAddIn_startup
:
((Excel.AppEvents_Event)Application).NewWorkbook += new Excel.AppEvents_NewWorkbookEventHandler(App_NewWorkbook);
Application.WorkbookBeforeClose += new Excel.AppEvents_WorkbookBeforeCloseEventHandler(App_WorkbookBeforeClose);
Application.WorkbookOpen += new Excel.AppEvents_WorkbookOpenEventHandler(App_NewWorkbook);
На этом уровне все работает нормально.
Затем я создал 3 элемента управления вкладки пользователя (с .cs
файл для каждого, конечно) для отображения в 3 CustomTaskPanes.Я создал 3 CustomTaskPanes в обработчике событий load
на вкладке ленты и написал функции для отображения соответствующей панели задач и соответствующей вкладки внутреннего элемента управления.Вот частичный код ленты.cs, показывающий, как я создал и отображал CustomTaskPane:
private CustomTaskPane tsPane;
private void tsFinStRibbon_Load(object sender, RibbonUIEventArgs e)
{
// Custom task pane
tsPane = Globals.ThisAddIn.CustomTaskPanes.Add(new tsDataControl(), "Data", Globals.ThisAddIn.Application.ActiveWindow);
tsPane = Globals.ThisAddIn.CustomTaskPanes.Add(new tsStControl(), "Statements", Globals.ThisAddIn.Application.ActiveWindow);
tsPane = Globals.ThisAddIn.CustomTaskPanes.Add(new tsPubControl(), "Publishing", Globals.ThisAddIn.Application.ActiveWindow);
tsPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
tsPane.Visible = false;
}
// Données
private tsDataControl setDataPane()
{
tsPane = Globals.ThisAddIn.CustomTaskPanes[0];
tsDataControl control = tsPane.Control as tsDataControl;
if (!tsPane.Visible)
{
tsPane.Width = 320;
tsPane.Visible = true;
}
return control;
}
// Etats
private tsStControl setStPane()
{
tsPane = Globals.ThisAddIn.CustomTaskPanes[1];
tsStControl control = tsPane.Control as tsStControl;
if (!tsPane.Visible)
{
tsPane.Width = 320;
tsPane.Visible = true;
}
return control;
}
// Publications
private tsPubControl setPubPane()
{
tsPane = Globals.ThisAddIn.CustomTaskPanes[2];
tsPubControl control = tsPane.Control as tsPubControl;
if (!tsPane.Visible)
{
tsPane.Width = 320;
tsPane.Visible = true;
}
return control;
}
// Balance générale
private void tsBtn1A_Click(object sender, RibbonControlEventArgs e)
{
if(Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsDataControl control = setDataPane();
control.selectTab(0);
}
}
// balance tiers
private void tsBtn1B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsDataControl control = setDataPane();
control.selectTab(1);
}
}
// Calcul des états
private void tsBtn2A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(0, btnId);
}
}
// -- Calcul des états avec notes annexes
private void tsBtn2A1_Click(object sender, RibbonControlEventArgs e)
{
if(Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(0, btnId);
}
}
// -- Calcul des états sans notes annexes
private void tsBtn2A2_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(0, btnId);
}
}
// Bilan
private void tsBtn2B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Bilan actif
private void tsBtn3A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Bilan Passif
private void tsBtn3B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
Когда я открываю Excel, я могу получить доступ к соответствующей панели задач и вкладке во внутреннем элементе управления только изисходная таблица.Любая дополнительная электронная таблица, которую я открываю или создаю, предоставляет вкладку ленты, но когда я нажимаю на любую из ее кнопок, пользовательские панели задач не отображаются.
Я пытался создать панели задач из файла ThisAddIn.cs
,и он эффективно создает их, но они реагируют только тогда, когда я нажимаю на ленту из исходной электронной таблицы.
В моем чтении я не смог найти способ эффективно прикрепить ленту к панелям задач, чтобы она работалаправильно.
Кто-нибудь есть идеи, как это исправить?
Спасибо.
РЕДАКТИРОВАТЬ
Вот полный ThisAddIn.cs
код:
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Events handlers
((Excel.AppEvents_Event)Application).NewWorkbook += new Excel.AppEvents_NewWorkbookEventHandler(App_NewWorkbook);
Application.WorkbookBeforeClose += new Excel.AppEvents_WorkbookBeforeCloseEventHandler(App_WorkbookBeforeClose);
Application.WorkbookOpen += new Excel.AppEvents_WorkbookOpenEventHandler(App_NewWorkbook);
}
private void setRibbonControlState(ref bool isEnabled)
{
int workbookCount = Application.Windows.Count;
if (workbookCount > 1 && !isEnabled)
return;
tsFinStRibbon ribbon = Globals.Ribbons.tsFinStRibbon;
int tabCount = ribbon.Tabs.Count;
for (int i = 0; i < tabCount; i++)
{
RibbonTab tab = ribbon.Tabs[i];
int grpCount = tab.Groups.Count;
for (int j = 0; j < grpCount; j++)
{
RibbonGroup grp = tab.Groups[j];
int itCount = grp.Items.Count;
for (int k = 0; k < itCount; k++)
{
grp.Items[k].Enabled = isEnabled;
}
}
}
if (!isEnabled)
{
int paneCount = CustomTaskPanes.Count;
for (int i = 0; i < paneCount; i++)
CustomTaskPanes[i].Visible = false;
}
}
private void App_NewWorkbook(Excel.Workbook Wb)
{
// Set the ribbon
bool isEnabled = true;
setRibbonControlState(ref isEnabled);
}
private void App_WorkbookBeforeClose(Excel.Workbook Wb, ref bool Cancel)
{
bool isEnabled = (Cancel) ? false : true;
setRibbonControlState(ref isEnabled);
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
Вот полный tsFinRibbon.cs
код:
public partial class tsFinStRibbon
{
//static private Dictionary<string, CustomTaskPane> tsDPanes = new Dictionary<string, CustomTaskPane>();
private CustomTaskPane tsPane;
private void tsFinStRibbon_Load(object sender, RibbonUIEventArgs e)
{
// Custom task pane
Globals.ThisAddIn.CustomTaskPanes.Add(new tsDataControl(), "Data");
Globals.ThisAddIn.CustomTaskPanes.Add(new tsStControl(), "Statements");
Globals.ThisAddIn.CustomTaskPanes.Add(new tsPubControl(), "Publishing");
}
// Data task pane call
private tsDataControl setDataPane()
{
tsPane = Globals.ThisAddIn.CustomTaskPanes[0];
tsDataControl control = tsPane.Control as tsDataControl;
if (!tsPane.Visible)
{
tsPane.Width = 320;
tsPane.Visible = true;
}
return control;
}
// Statement task pane call
private tsStControl setStPane()
{
tsPane = Globals.ThisAddIn.CustomTaskPanes[1];
tsStControl control = tsPane.Control as tsStControl;
if (!tsPane.Visible)
{
tsPane.Width = 320;
tsPane.Visible = true;
}
return control;
}
// Publications task pane call
private tsPubControl setPubPane()
{
tsPane = Globals.ThisAddIn.CustomTaskPanes[2];
tsPubControl control = tsPane.Control as tsPubControl;
if (!tsPane.Visible)
{
tsPane.Width = 320;
tsPane.Visible = true;
}
return control;
}
// Balance générale
private void tsBtn1A_Click(object sender, RibbonControlEventArgs e)
{
if(Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsDataControl control = setDataPane();
control.selectTab(0);
}
}
// balance tiers
private void tsBtn1B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsDataControl control = setDataPane();
control.selectTab(1);
}
}
// Calcul des états
private void tsBtn2A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(0, btnId);
}
}
// -- Calcul des états avec notes annexes
private void tsBtn2A1_Click(object sender, RibbonControlEventArgs e)
{
if(Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(0, btnId);
}
}
// -- Calcul des états sans notes annexes
private void tsBtn2A2_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(0, btnId);
}
}
// Bilan
private void tsBtn2B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Bilan actif
private void tsBtn3A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Bilan Passif
private void tsBtn3B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Bilan N-1
private void tsBtn3C_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Haut du bilan
private void tsBtn3D_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// -- Bas du bilan
private void tsBtn3E_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(1, btnId);
}
}
// Compte de résultat
private void tsBtn2C_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(2, btnId);
}
}
// -- Compte de résultat charges
private void tsBtn4A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(2, btnId);
}
}
private void tsBtn4B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(2, btnId);
}
}
private void tsBtn4C_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(2, btnId);
}
}
private void tsBtn4D_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(2, btnId);
}
}
// Flux de trésorerie
private void tsBtn2D_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(3, btnId);
}
}
private void tsBtn5A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(3, btnId);
}
}
private void tsBtn5B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonButton btn = (RibbonButton)sender as RibbonButton;
string btnId = btn.Name;
control.selectTab(3, btnId);
}
}
private void tsBtn5C_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(3, btnId);
}
}
private void tsBtn5D_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(3, btnId);
}
}
// Annexes
private void tsBtn6A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsStControl control = setStPane();
RibbonSplitButton btn = (RibbonSplitButton)sender as RibbonSplitButton;
string btnId = btn.Name;
control.selectTab(4, btnId);
}
}
private void tsBtn7A_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsPubControl control = setPubPane();
control.selectTab(0);
}
}
private void tsBtn7B_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsPubControl control = setPubPane();
control.selectTab(1);
}
}
private void tsBtn7C_Click(object sender, RibbonControlEventArgs e)
{
if (Globals.ThisAddIn.CustomTaskPanes.Count != 0)
{
tsPubControl control = setPubPane();
control.selectTab(2);
}
}
}
Я немного изменил обработчик события загрузки вкладки пользовательской ленты.Использование свойства tspane
не имело значения.Обработчик события загрузки пользовательской вкладки ленты создает три пользовательских панели задач.Каждый из них относится к определенной группе кнопок ленты.При нажатии кнопки в группе вызывается соответствующая область задач и активируется соответствующий элемент tabControl на панели задач.
Как я уже говорил, при открытии Excel только исходная рабочая книга возвращает пользовательскую задачупри нажатии кнопки ленты.
Я также заметил, что когда я открываю Excel, создаю / открываю вторую рабочую книгу и нажимаю кнопку ленты на вкладке пользовательской ленты, панель задач, которая отображается на панели инструментов.Начальная рабочая книга реагирует и активирует правильную вкладку или область задач.