none
PowerPoint 2010: Problem when invalidating the ribbon with multiple presentations open RRS feed

  • Question

  • Hi,

    I am developing an addin handling several office 2010 programs (Word, Excel, PowerPoint, Project and Visio). In the addin I have a backstage tab showing some custom properties. To sometimes update the tab I use Invalidate or InvalidateControl("controlName"). In the callbacks I use control.Context to check which window, when multiple documents are open, to get the properties from. This works well for all applications but PowerPoint.

    In PowerPoint control.Context always seems to point at the active window. As a result every presentation shows the same properties as the active presentation. Is this a bug in PowerPoint? Is there a way to get around this problem?

    Regards

    Thursday, May 2, 2013 7:04 PM

All replies

  • >I am developing an addin handling several office 2010 programs (Word, Excel, PowerPoint, Project and Visio).

    a shared addin?

    you can upload a sample project for us to repro your issue.


    Regards,
    Fermin
    What's life without whimsy?

    Friday, May 3, 2013 12:10 PM
  • Hi Fermin,

    Yes, its a shared addin.

    Below you find sample code that illustrates the problem. To build it, make a new project (I am using VS10 and vb.net) for a shared add-in and set Word and PowerPoint as Application Hosts. Then copy the code to connect.vb. You also need to add reference to Microsoft.Office.Interop.Word and PowerPoint.

    Now start Word. You should find the new tab TestTab under File. Make a new document so that you have two new documents. Go to the tab TestTab for both documents and you find the name of each document. Press Invalidate. The name is still correct on each document.

    Now start PowerPoint. Do the same thing with two presentations opened. Now when you press Invalidate, the name changes so that both presentations shows the name of the active presentation.  

    Regards

    imports Extensibility
    imports System.Runtime.InteropServices
    Imports Office = Microsoft.Office.Core
    Imports Word = Microsoft.Office.Interop.Word
    Imports PowerPoint = Microsoft.Office.Interop.PowerPoint
    <GuidAttribute("25380ABF-A23B-47DD-85BA-177F3BB2DB52"), ProgIdAttribute("SampleAddin.Connect")> _
    Public Class Connect
    	
        Implements Extensibility.IDTExtensibility2, Office.IRibbonExtensibility
    	Private applicationObject As Object
            Private addInInstance As Object
        Private ribbon As Office.IRibbonUI
    	Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdown
    	End Sub
    	
    	Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
    	End Sub
    	
    	Public Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupComplete
    	End Sub
    	
    	Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnDisconnection
    	End Sub
    	
    	Public Sub OnConnection(ByVal application As Object, ByVal connectMode As Extensibility.ext_ConnectMode, ByVal addInInst As Object, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnConnection
    		applicationObject = application
    	        addInInstance = addInInst
    	End Sub
        Public Function GetCustomUI(ByVal ribbonID As String) As String Implements Office.IRibbonExtensibility.GetCustomUI
            Dim sCustomUI As String =
                "<?xml version=""1.0"" encoding=""UTF-8""?> " +
                "<customUI onLoad=""LoadRibbon"" xmlns=""http://schemas.microsoft.com/office/2009/07/customui"">" +
                "<backstage>" +
                "<tab id=""tTab"" label=""TestTab"" insertAfterMso=""TabInfo"" title=""TestTab"">" +
                "<firstColumn>" +
                "<group id=""gGroup"" label=""Name"">" +
                "<topItems>" +
                "<labelControl id=""lcName"" getLabel=""GetLabel""/>" +
                "<button id=""bInvalidate"" label=""Invalidate"" onAction=""OnAction""/>" +
                "</topItems>" +
                "</group>" +
                "</firstColumn>" +
                "</tab>" +
                "</backstage>" +
                "</customUI>"
            Return sCustomUI
        End Function
        Public Sub LoadRibbon(ByVal ribbonUI As Office.IRibbonUI)
            ribbon = ribbonUI
        End Sub
        Public Function GetLabel(ByVal control As Office.IRibbonControl) As String
            If TypeOf applicationObject Is Word.Application Then
                Try
                    Dim oWin As Word.Window = CType(control.Context, Word.Window)
                    Return oWin.Document.Name
                Catch ex As Exception
                    ' No document opened
                    Return ""
                End Try
            Else 'TypeOf applicationObject Is PowerPoint.Application
                Try
                    Dim oWin As PowerPoint.DocumentWindow = CType(control.Context, PowerPoint.DocumentWindow)
                    Return oWin.Presentation.Name
                Catch ex As Exception
                    ' No document opened
                    Return ""
                End Try
            End If
        End Function
        Sub OnAction(ByVal control As Office.IRibbonControl)
            ribbon.Invalidate()
        End Sub
    End Class



    • Edited by SteffenAd Sunday, May 5, 2013 4:34 AM
    Saturday, May 4, 2013 6:04 AM
  • So the issue is that PowerPoint exposes only one RibbonUI and updates both or several documents (side by side) when you invalidate the UI.  That sounds like a major bug in VSTO Ribbon XML, which is probably why Fermin did not respond.
    Monday, January 13, 2014 6:19 PM
  • Hello Steffen,

    Did you try to change the active PowerPoint window? Do you get the Ribbon UI updated then?

    Tuesday, January 14, 2014 4:26 PM
  • Both update.  That's the point.

    Add a label to the firstColumn Ribbon.xml.  Put two PowerPoint presentations side by side.  Go to the Print back stage and have the code invalidate the RibbonUI.  Both instances will be updated with the changed value, not just the one with the current presentation.  That is why we need more than one RibbonUI reference.

    Tuesday, January 14, 2014 8:43 PM
  • Well, Outlook updates their inspector windows on demand. I.e. if you select the first inspector window and call the Invalidate method to refresh the custom Ribbon UI, the second inspector window will not be refreshed until you activate it (callbacks are not called until you select the window).

    That is by design in Fluent UI.

    Tuesday, January 14, 2014 8:52 PM