blog community

Welcome to blog community Sign in | Join | Help
in Search

Wouter van Vugt

This blog is no longer maintained and has moved

Working with VSTO TaskPanes

One of the cool new things you can do with VSTO 2005 SE is create App-Level taskpanes for the latest two Office releases (2003, and of course 2007). The basic code to demo this during various VSTO sessions takes the following form:

CustomTaskPanes.Add(new MyCoolUserControl(), "Wow, a P4n3!");

Some of you who came to the Office Developer Events noticed that if you take the basic code used in many demos the behavior of your taskpane is not quite what you might expect. The problem? Well, besides showing the pane, also add a Ribbon customization to toggle the pane on and off. The new Ribbon button is displayed in each window, but the taskpane you've added is only shown in the primary document window. So, opening new windows using CTRL_N does show the ribbon button, but doesn't show the taskpane.

This is of course possible using the VSTO object model, but you need an extra 'window' parameter for the method call displayed above. The downside, you need to administer in which Word / Excel / PowerPoint window the taskpane is displayed, and in which windows it isn't so you can take the appropriate action (create a new pane, or display the existing invisible pane). Below you can find a special manager class which you can use to toggle panes inside each window of your Office product.

First let me show you how to use it. In the ThisAddIn class, where you'd normally create your panes, you now create an instance of the TaskPaneContainer class, which manages your panes across the various open Office windows. (The VSTOPane Type is there because of an extra using VSTOPane = Microsoft.Office.Tools.CustomTaskPane statement)

public partial class ThisAddIn
{
  public TaskPaneContainer _myInfoPaneContainer = null;

  private void ThisAddIn_Startup(object sender, System.EventArgs e)
  {
    _myInfoPaneContainer = new TaskPaneContainer(
      new TaskPaneContainer.TaskPaneCreationCallback(CreateNewPane));
  }

  VSTOPane CreateNewPane(string title, Window parent)
  {
    return CustomTaskPanes.Add(new MyInfoUserControl(), title, parent);
  }
}

Next, add Ribbon support to your AddIn, and dump the existing OnToggleButton1 method, and replace it with the following code (I'll might update the code later to have a better experience):

public void OnToggleButton1(Office.IRibbonControl control, bool isPressed)
{
  if (isPressed)
  {
    Globals.ThisAddIn._myInfoPaneContainer.Show("Test Pane");
  }
  else
  {
    Globals.ThisAddIn._panes.HideCurrent();
  }
}

Before using it you need to understand one thing about the class. Each instance of TaskPaneContainer holds a specific type of taskpane, because it uses a callback method to create the CustomTaskPane instance. Now for that code as well (download it here):

public class TaskPaneContainer
{
  public delegate VSTOPane TaskPaneCreationCallback(string title, Window window);

  Dictionary<Window, VSTOPane> _panes = new Dictionary<Window, VSTOPane>();
  TaskPaneCreationCallback _paneCreationCallback;

  public TaskPaneContainer(TaskPaneCreationCallback paneCreationCallback)
  {
    _paneCreationCallback = paneCreationCallback;
  }

  public void Show(string title)
  {
    VSTOPane pane = null;
    Window activeWindow = Globals.ThisAddIn.Application.ActiveWindow;
    if (_panes.ContainsKey(activeWindow))
    {
      pane = _panes[Globals.ThisAddIn.Application.ActiveWindow];
    }
    else
    {
      pane = _paneCreationCallback(title, activeWindow);
      _panes.Add(activeWindow, pane);
    }
    pane.Visible = true;
  }

  public void HideCurrent()
  {
    Window activeWindow = Globals.ThisAddIn.Application.ActiveWindow;
    if (_panes.ContainsKey(activeWindow))
    {
      _panes[activeWindow].Visible = false;
    }
  }
}

Hope it helps!

[Edit] ps: To work correctly the code does need to do one extra thing. Clear up the dictionary of taskpanes when a window closes, otherwise a reference still exists in your user code, which is of course a bad bad thing. (and I noticed a public field, aiaiai, now where did I learn to program... :-P )

Published Wednesday, November 08, 2006 3:52 PM by wouterv
Filed under:

Comments

 

Evren Ok&#231;u said:

I've created a custom action pane in Microsoft Word 2007 by reading the msdn article- http://msdn2.microsoft.com/en-us/library/aa338197.aspx. I want to send the active document to a web service when user clicks a button on the custom action pane. I can get active document by the 'ActiveDocument' property of Application class but I can't get a stream of the document to pass it as a parameter of web service method. Is there a way of serializing active document? Or what's the best practice of sending the active document to a web service? Thanks..
November 23, 2006 12:23 AM
 

wouterv said:

Hi,

I believe that this is not supported. Reading a stream into the application (an image for instance) is also not possible. The workaround is to first save the document to a temp location and use a FileStream object from there.

Hope it helps

Wouter

November 23, 2006 11:18 AM
 

Ben said:

Are you sure you can create App-Level taskpanes in Office 2003 ? I hope you can but i think in 2003 it's only on Doc-Level http://msdn2.microsoft.com/en-us/library/aa722570.aspx
April 18, 2007 12:58 PM
 

wouterv said:

Hi Ben,

I believe you can using VSTO 2005 SE, but not 100% sure on that. Been using 2007 for quite some time now

April 19, 2007 7:56 AM
Anonymous comments are disabled

This Blog

Syndication

News


Add to Technorati Favorites
Powered by Community Server, by Telligent Systems