Managing documents from Custom Task Pane

I have been experimenting with VSTO 2005 SE and Office 2007 and would appreciate if someone could help me with the following:

I would like to open different documents using a custom task pane and switch between these documents. I can create and open the first document. When it comes to the second document, it gets created on a different window (where my custom task pane is not visible).

From the immediate window in the document VBA I can easily switch to another windows via Application.WIndows(index).Activate command. However I can't achieve the same result through the Add-In. Furthermore, the second document does not respond to the Ribbon button that toggles its display.

How can I programmatically switch to the second document and still have control over the custom task pane

 



Answer this question

Managing documents from Custom Task Pane

  • Mahmoud_Fayed

    Thank you all for your help so far.

    The suggestion to intercept the DocumentOpen event is good. However how to get the window from the new doc and use that to create a new custom task pane is beyond me.

    What I don't understand is: if VSTO SE addins for Office 2007 are Application level add-ins (opposed to document level) why do we need to create a new custom task pane for another document Why does the add-in rely on a null reference to the active document in order to provide a link between the ribbon and the CTP as a different document is opened

    What is the relationship between the task pane and the document


  • kencleary

    The way I was planning to do this was to use CustomTaskPanes.add(control, "Text", window) - since the 3rd arg is allows you to attach the CTP to a specific window. I'd use the event listening to catch a NewDocument or OpenDocument event that then calls this.

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
    Application.DocumentOpen += new Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentOpenEventHandler(Application_DocumentOpen);
    }

    void Application_DocumentOpen(Microsoft.Office.Interop.Word.Document Doc)
    {
    myUserControl1 = new UserControl1();
    // somehow get window from doc and use it in 3rd arg
    myCustomTaskPane = this.CustomTaskPanes.Add(myUserControl1, "MyTask Pane", docWindow);

    myCustomTaskPane.Width = 300;
    myCustomTaskPane.Visible = true;
    }

    But I haven't figured out how I get the appropriate window object given the Doc. Anyone help me

    Failing that, I'll try making sure the new/opened doc is the active one, so hopefully the new  CTP gets added to it.  Currently, I have it sometimes adding the new CTP to an old window rather than the new - so I end up with 2 CTPs on one window.

    Cheers
    Paul.

  • Jamie Ward

    Hi Helio

    Word (and Outlook) are special in the Office world in that the Windows are divorced from the "application". If you were developing an Add-in for Excel, for example, you wouldn't be having this problem because Excel manages only a single window - it's a true MDI interface. Word is something in between a SDI and a MDI, making some things extremely complicated (to put it mildly). That's why you have to jump through hoops for Word.



  • asalcedo

    Thank you for the info Paul. You're right when you said "one thing to remember is that opening a new window does not run your add-in initialization code again."

    This is what I noticed and this the workaround (or hack) I had to do to solve my problem:

    If you open an existing document, say Test.Docx from the add-in having an active document already open, say Document1.docx, then Test.Docx will not initialise the CTP and will not response to the ribbon events.

    In order to solve my problem I had to make sure I closed the active document (Document1.docx) before I could open the next document (Test.docx). For example:

    ' Close active document

    _app.ActiveDocument.Close()

    'Now open the other document

    _doc = _app.Documents.Open("C:\Test.docx")

    _doc.Activate()

    There should be a better way of doing this without having to close the active document all the time. What I've got so far will do the trick though - but it would be nice to be able to smoothly switch between open documents and avoid the screen flicker when you have to close/open a document.

    Helio


  • kawano1h

    Hi Helio

    The alternate approach would be to trap the application's DocumentNew and DocumentOpen events and generate an additional taskpane for each window. Here's an excerpt from a discussion in the vsnet.vstools.office newsgroup that outlines this

    "You mean Office.ICustomTaskPaneConsumer If you Implement that you get a CTPFactoryAvailable event that passes an instance of Office.ICTPFactory. That has a CreateCTP method.What I've found, at least for Outlook is I supply either Inspector or Explorer as the Window argument. If I use the VSTO CustomTaskPanes collection (Cypress) there's no Window argument and you can't specify where the CTP is going to be bound. It ends up in the default Explorer.

    Using a RequestService override to work with ICustomTaskPaneConsumer lets me specify where to bind the CTP. For Word I'd use Word.Window in place of Inspector or Explorer." (Ken Slovak)

    I understand the VSTO team is working on documentation to illustrate this, but I don't know when it will be available.



  • kull

    I think the CTP is linked to the window, not the document. You can close the document, but keep the CTP open. What I need to look into is managing the relationship between windows, CTPs and docs - so any pointers to documentation from anyone would help me.

    Cheers
    Paul

  • rusty_bone

    VSTO add-ins are document specific by design for security and other reasons unlike VBA add-ins which are generic and are accessible to all documents, whether the functionality is needed or not.


  • Blakeyrat

    Actually VSTO SE addins for Office 2007 are Application level add-ins, not document centric like the original VSTO templates. The Orcas release of VSTO should have the Office 2007 document centric add-ins.

    That said, let me see if I can restate the problem and possibly a path to follow. You have a ribbon button that displays the CTP. That CTP then opens a new document (in a new window) which doesn't include the CTP. One thing to remember is that opening a new window does not run your add-in initialization code again. It's run once when the application is started, a new window does not equal a new instance of the application. So when your new document is opened (and I haven't tested this so I could be way off) I would think you'd need to get a reference to that window and then programmtically open the task pane. That should create a NEW instance of your CTP. If you want to share information across CTP instances than you can use Shared variables, just keep multithreading issues in mind.

    I hope this helps some,



  • Managing documents from Custom Task Pane