Using Visual Studio 2005 Tools for the Office System SE to Create Add-Ins with Custom Task Panes in PowerPoint 2007
Applies to: 2007 Microsoft Office System, Microsoft Office PowerPoint 2007, Visual Studio 2005, Visual Studio 2005 Tools for Office Second Edition
Ken Getz, MCW Technologies, LLC
In this demonstration, you create a custom task pane that creates a slide, inserting a selected date into the title of the slide, and an Office Fluent Ribbon customization that adds a button to the Insert tab in Office PowerPoint 2007 to show and hide the task pane. To demonstrate the technique, follow these steps.
To create a custom task pane
In Visual Studio 2005, on the File menu, point to New,and then click Project. After you select the language (Visual Basic or C#), expand the Office node, and select Office 2007 Add-Ins. In the Templates pane, select PowerPoint Add-In. Name the new project CustomTaskPaneAddIn.
Visual Studio creates two projects in the solution. The first project contains your add-in, and the second project contains a Setup project that you can use when you distribute your add-in.
Add the custom task pane. In the Visual Studio menu, click Project. Click Add User Control, name the control DateCustomTaskPane, and click Add.
Because VSTO 2005 SE treats a standard User Control as a custom task pane designer, this action adds a new user control/custom task pane item to your project.
In the ThisAddIn class, add an Imports statement or a using statement so that you can easily refer to classes within the Microsoft.Office.Tools namespace, which provides the CustomTaskPane class you use.
To add a variable
In the ThisAddIn class, add a variable that can refer to your custom task pane.
To modify ThisAddIn_Startup
In the ThisAddIn class, modify the ThisAddIn_Startup procedure. Add the following code to create a new custom task pane by using the DateCustomTaskPane class you just created, set its width, and make it visible.
ctp = Me.CustomTaskPanes.Add( _ New DateCustomTaskPane(), "Select and Insert Date") ctp.Width = 200 ctp.Visible = True
Save and run your project. Visual Studio 2005 loads a copy of PowerPoint, and runs your add-in, which displays the Select and Insert Date task pane.
Quit PowerPoint when you are done.
Add controls to the task pane
After you create the empty task pane and verify that it works, you can add a MonthCalendar control and a Button control to the task pane. Users can select a date, click the button, and insert the selected date at the current location in the current slide.
To add a MonthCalendar control and a Button control
In the Solution Explorer window, double-click DateCustomTaskPane.vb or DateCustomTaskPane.cs, loading it into the designer window.
Expand the size of the design surface for the task pane—it should be large enough to contain a MonthCalendar control and a Button control. Set the Size property of the task pane to 300, 400.
In the Properties window, set the Font property for the task pane to Segoe UI, 8.25pt.
If the Toolbox window is not visible, click View and then click Toolbox. From the Common Controls tab of the Toolbox window, drag a MonthCalendar control and a Button control onto the task pane. Set the Name properties for the controls to monthCalendar and insertButton.
Modify the button's Text property to Insert the selected date. When you are done, the task pane should look like Figure 1.
To add code that inserts the selected date into the current slide
In the task pane designer, double-click the button, loading the code editor with the Click event stub created.
In C# only, add the following statement to the top of the code file.
To replace insertButton_Click
Replace the existing insertButton_Click procedure stub with the following procedure.
Private Sub insertButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insertButton.Click Dim presentation As PowerPoint.Presentation = _ Globals.ThisAddIn.Application.ActivePresentation If presentation IsNot Nothing Then Dim slide As PowerPoint.Slide = _ presentation.Slides.Add( _ presentation.Slides.Count + 1, _ PowerPoint.PpSlideLayout.ppLayoutText) slide.Shapes(1).TextFrame.TextRange.Text = _ monthCalendar.SelectionStart.ToShortDateString() slide.Select End If End Sub
This code retrieves a reference to the active presentation, if it exists. The code creates a new slide, adding it at the end of the current presentation. Finally, the code takes the SelectionStart property of the MonthCalendar control, and adds its value to the TextFrame in the TextRange of the first shape on the slide. For a text slide, that is the title of the slide.
Save and run the project. In the custom task pane, select a date, and click the button. The task pane's code inserts the selected date as the title of a new slide.
Quit PowerPoint and return to Visual Studio 2005.
Display the custom task pane on demand
What happens if the user closes the custom task pane? How does the user reopen it? In addition, what if a customer does not want the custom task pane displayed each time PowerPoint starts up? You need a way to display the task pane on demand. One way to do that is by using a toggle button on an Office Fluent Ribbon customization. The user can close the task pane, and so the state of the toggle button needs to reflect the state of the task pane. That is, you need a way to refresh the display of the button, based on the state of the task pane. Follow these steps to add this support.
To add the Office Fluent Ribbon customization
To add the Office Fluent Ribbon customization, in the Solution Explorer window, right-click the add-in project and from the context menu, select Add, and then click New Item.
In the Add New Item dialog box, select Ribbon support. Click Add to insert the new Office Fluent Ribbon customization.
Modify the new Ribbon1.xml file, replacing the existing content with the following XML. This customization adds a new group to the existing Insert tab on the Office Fluent Ribbon. On this tab, the markup adds a new toggle button displaying the text Date Task Pane.
Close and save Ribbon1.xml.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad"> <ribbon> <tabs> <tab idMso="TabInsert"> <group id="MyGroup" label="How To"> <toggleButton id="toggleButton1" size="large" label="Date Task Pane" screentip="Display the date task pane" onAction="OnToggleButton1" imageMso="DateAndTimeInsert" /> </group> </tab> </tabs> </ribbon> </customUI>
Load Ribbon1.xml as a resource
The add-in must load the Ribbon1.xml file at runtime. By default, the template includes a procedure that handles this in a standard, although tricky, way. It is easier to load the Ribbon1.xml file as a resource.
To load Ribbon1.xml as a resource
In the Solution Explorer window, right-click the CustomTaskPaneAddIn project, and select Properties from the context menu.
In the Properties pane, click the Resources tab.
From the Solution Explorer window, drag the Ribbon1.xml file into the Properties pane. This action adds the Ribbon1.xml file as a project resource.
Close the Properties pane, and click Yes when prompted to save.
At runtime, the add-in calls a special procedure in order to load a copy of your Office Fluent Ribbon customization, and you must add that procedure. The add-in template includes the procedure—you must uncomment it. In the Ribbon1.vb or Ribbon1.cs file, uncomment the ThisAddIn partial class.
To modify GetCustomUI
In the Ribbon1 class, modify the existing GetCustomUI implementation so that it retrieves the Ribbon1 resource. In C#, you must expand the IRibbonExtensibility members code region to find the procedure.
Add a callback procedure
When you customize the Office Fluent Ribbon, you must add callback procedures to handle events of the Office Fluent Ribbon controls. In this case, the template created the procedure for you. The default behavior of the template Ribbon support adds a ToggleButton control to the Office Fluent Ribbon, and the template adds the callback procedure.
To modify OnToggleButton1
In the Ribbon1 class, expand the Ribbon Callbacks code region to find the existing OnToggleButton1 procedure.
You want the OnToggleButton1 procedure to toggle the visibility of the task pane. The Office Fluent Ribbon passes the isPressed value that indicates whether the toggle button has been pressed or not.
Replace the existing procedure with the following code.
Public Sub OnToggleButton1( _ ByVal control As Office.IRibbonControl, _ ByVal isPressed As Boolean) Globals.ThisAddIn.ctp.Visible = isPressed End Sub
Refresh the status of the button
You also need a way to refresh the status of the button, based on the state of the custom task pane. To do that, you must call the InvalidateControl method of the Office Fluent Ribbon, passing the name of the control to refresh.
To add a Refresh procedure
In the Ribbon1 class, add the following procedure, which you call when the visibility of the task pane changes.
Display the toggle button
You want to determine whether the toggle button should appear pressed or not, based on the visibility of the task pane. The ToggleButton control provides an attribute, getPressed, that allows you to specify the name of a procedure it will call, as the Office Fluent Ribbon refreshes its display, to determine whether it should appear pressed.
To add a GetPressed procedure
Add the following procedure to the Ribbon1 class.
Public Function GetPressed( _ ByVal control As Office.IRibbonControl) As Boolean Return Globals.ThisAddIn.ctp.Visible End Function
To modify Ribbon1.xml
From the Solution Explorer window, re-open the Ribbon1.xml file. Modify the XML, adding the getPressed attribute.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad"> <ribbon> <tabs> <tab idMso="TabAddIns"> <group id="MyGroup" label="My Group"> <toggleButton id="toggleButton1" size="large" label="Date Task Pane" screentip="Display the date task pane" onAction="OnToggleButton1" getPressed="GetPressed" imageMso="DateAndTimeInsert" /> </group> </tab> </tabs> </ribbon> </customUI>
To add a Refresh procedure
The custom task pane should refresh the Office Fluent Ribbon when it changes its visibility. The CustomTaskPane class raises the VisibleChanged event for this purpose. In the ThisAddIn class, add the following procedure.
Private Sub HandleVisibleChanged( _ ByVal sender As Object, ByVal e As EventArgs) ribbon.Refresh() End Sub
To hook up the event handler
To hook up the event handler, add the following code to the end of the existing ThisAddIn_Startup procedure.
To unhook the event handler
To unhook the event handler, add the following code to the existing ThisAddIn_Shutdown procedure.
Save and run the project. In the running instance of PowerPoint 2007, click the Insert tab. Verify that the task pane is visible, and that the button is pressed. "Unpress" the button, and verify that the task pane disappears. Press the button again, displaying the task pane.
Close the task pane manually by clicking the x in the upper-right corner.
The Office Fluent Ribbon button changes its state.
Close PowerPoint when you are done, returning to Visual Studio.
The steps in this walkthrough describe the details of building an add-in using VSTO 2005 SE, whether you are targeting PowerPoint, or any other of the supported Office 2007 products. It is important to realize that Office Fluent Ribbon customizations do not provide a direct means of interacting with controls on the Office Fluent Ribbon. For example, your code cannot select or unselect the toggle button when the user closes the task pane. Instead, you must force the Office Fluent Ribbon to refresh the control's display. Forcing a refresh causes the Office Fluent Ribbon to rerun its getPressed event handler, which determines from the visibility of the task pane how the task pane should be displayed. That is the only way to accomplish this sort of goal when customizing the Office Fluent Ribbon.
You should also consider whether to have your task pane displayed as the application loads. In general, this is not a good idea. You should load the task pane only on demand. To make this change in the sample, remove the code that sets the Visible property of the task pane to True in the startup code.
Finally, consider where to add your button that displays the task pane. Try to find an existing tab for your button. In this case, it makes sense to place the button on the existing Insert tab, because you are inserting data into the current presentation.