Excel VSTO Доступность настраиваемой панели задач - PullRequest
0 голосов
/ 27 февраля 2019

Я пишу 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, создаю / открываю вторую рабочую книгу и нажимаю кнопку ленты на вкладке пользовательской ленты, панель задач, которая отображается на панели инструментов.Начальная рабочая книга реагирует и активирует правильную вкладку или область задач.

1 Ответ

0 голосов
/ 28 февраля 2019

Я наконец понял это.Пользовательские панели задач должны быть созданы для каждого окна, в котором оно должно отображаться.Поскольку я думал, что настраиваемые панели задач привязаны к приложению, а не к какой-либо конкретной книге, я просто создал 3 из них только один раз.

Итак, я создал словарь для отслеживания создаваемых панелей задач иего положение в CustomTaskPaneCollection, так что я могу вызывать / или создавать (при необходимости) любую панель задач при переключении окон Excel.Вот коды клавиш:

    private CustomTaskPane tsPane;
    private int Wn;
    private Dictionary<string, int> dict;

    private void tsFinStRibbon_Load(object sender, RibbonUIEventArgs e)
    {
        // Create a dictionary of indexes
        dict = new Dictionary<string, int>();
    }
    // Données
    private tsDataControl setDataPane()
    {
        // Initialize the window ID and pane name
        Wn = Globals.ThisAddIn.Application.Hwnd;
        string paneName = "Data" + Wn.ToString();

        // Check if the CTP already exists and create it otherwise
        if (!dict.ContainsKey(paneName))
        {
            tsPane = Globals.ThisAddIn.CustomTaskPanes.Add(new tsDataControl(), paneName);
            dict.Add(paneName, Globals.ThisAddIn.CustomTaskPanes.Count - 1);
        }
        else
        {
            tsPane = Globals.ThisAddIn.CustomTaskPanes[dict[paneName]];
        }

        // Get the tab control
        tsDataControl control = tsPane.Control as tsDataControl;

        if (!tsPane.Visible)
        {
            tsPane.Width = 320;
            tsPane.Visible = true;
        }

        return control;
    }

    // Etats
    private tsStControl setStPane()
    {
        // Initialize the window ID and pane name
        Wn = Globals.ThisAddIn.Application.Hwnd;
        string paneName = "Statement" + Wn.ToString();

        // Check if the CTP already exists and create it otherwise
        if (!dict.ContainsKey(paneName))
        {
            tsPane = Globals.ThisAddIn.CustomTaskPanes.Add(new tsStControl(), "Statement");
            dict.Add(paneName, Globals.ThisAddIn.CustomTaskPanes.Count - 1);
        }
        else
        {
            tsPane = Globals.ThisAddIn.CustomTaskPanes[dict[paneName]];
        }

        // Get the tab control
        tsStControl control = tsPane.Control as tsStControl;

        // Display the pane
        if (!tsPane.Visible)
        {
            tsPane.Width = 320;
            tsPane.Visible = true;
        }

        return control;
    }

    // Publications
    private tsPubControl setPubPane()
    {
        // Initialize the window ID and pane name
        Wn = Globals.ThisAddIn.Application.Hwnd;
        string paneName = "Publishing" + Wn.ToString();

        // Check if the CTP already exists and create it otherwise
        if (!dict.ContainsKey(paneName))
        {
            tsPane = Globals.ThisAddIn.CustomTaskPanes.Add(new tsPubControl(), paneName);
            dict.Add(paneName, Globals.ThisAddIn.CustomTaskPanes.Count - 1);
        }
        else
        {
            tsPane = Globals.ThisAddIn.CustomTaskPanes[dict[paneName]];
        }

        // Get the tab control  
        tsPubControl control = tsPane.Control as tsPubControl;

        // Display the pane
        if (!tsPane.Visible)
        {
            tsPane.Width = 320;
            tsPane.Visible = true;
        }

        return control;
    }

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...