PowerPoint 2010 Custom TaskPane in multple windows - c#

I am developing a custom task pane for Microsoft PowerPoint 2010. I need the task pane to be synchronized between multiple application windows/presentations. The task panes are displayed using a toggle button on the ribbon.
Since PowerPoint 2010 displays each presentation in a different document window (which is different from 2007), I need to create a task pane separately for each window and synchronize them. I have followed the Microsoft tutorial on how to create task panes for multiple application windows, and I am using the CustomTaskPaneCollection.Add(UserControl, String, Object) method to specify which application window the task pane should be associated with. In this case the Object is the PowerPoint.DocumentWindow that the task pane should be associated with.
For some reason all of my task panes are created in the active window and not the window that I assign. For example, if I open 3 PowerPoint presentations and then toggle the task pane, all three task panes will be added to the active window.
This is the code I am using to add the task panes when the toggle is pressed:
public void AddAllTaskPanes()
{
PowerPoint.DocumentWindows windows = Globals.ThisAddIn.Application.Windows;
if(windows.Count > 0)
{
for (int i=1; i<=windows.Count; i++){
PowerPoint.DocumentWindow window = windows[i];
customTaskPane = this.CustomTaskPanes.Add(new UserControl1(), "My User Control", window);
customTaskPane.Visible = true;
}
}
}
It seems that this should successfully add each task pane to its specified window, and I cannot figure out why all of the task panes are being associate with the active window instead. I have done a lot of research into this issue and have not been able to find a solution. The closest I have found was this question, however the answer corresponds to PowerPoint 2007 and not 2010 like the question references.
Any insight into why PowerPoint may be behaving this way would be greatly appreciated.

I went the way of creating the TaskPanes from the PresentationAfterOpen and PresentationAfterNew Events which produces the same behaviour.
A note about the PresentationAfterOpen event, if the document selected by the user is already open, the event is still fired so you need to check if the CustomTaskPane has already been created for that document before creating a new one.
A way to overcome this problem is to create a pointer to the associated DocumentWindow in your CustomPane and enumerate through the CustomTaskPaneCollection checking for the associated one.

Related

Adding to Ribbon at run time works once

Hi I'm trying to add the current open contacts phone numbers to a ribbon.
I have created the ribbon and added a SplitButton which will contain the phone numbers.
In 'ThisAddin' when the current explorer changes it triggers an event which simply gets the item type. If its a contact it calls
//ThisAddin.cs on explorer change event - if is contact run:
Globals.Ribbons.CallContact.AddButton(contactItem.BusinessTelephoneNumber);
//Ribbon class
internal void AddButton(string name)
{
if (name != null && name.Count() > 2)
{
RibbonButton item = Globals.Factory.GetRibbonFactory().CreateRibbonButton();
item.Label = name;
item.ShowLabel = true;
this.newSplit.Items.Add(item);
}
}
This works once, first time opening a contact the phone number is displayed in the ribbon. Opening another contact window will cause the ribbon items to be added but are blank and null.
I'm simply trying to add the contacts phone numbers to the ribbon and leave them there while the user can open another contact and the same code runs adding the phone numbers to the ribbon.
I don't need to keep reference to the items once they are added. Thank you for the help. I feel there needs to be an invoke in here somewhere.
You must tell Outlook to refresh the ribbon. See https://learn.microsoft.com/en-us/visualstudio/vsto/walkthrough-updating-the-controls-on-a-ribbon-at-run-time?view=vs-2019 for the sample code.
You will need to specify a callback to retrieve the button's caption instead of hard-coding it in the ribbon's XML.
Note that since you can have multiple inspectors open, you must provide data specific to each item opened in its own inspector.
The Ribbon UI is a static thing because it is loaded once at startup (or before the window is shown). The best what you can do is to define callbacks and get them called wherever you need. For example, you can define 'getVisible' callback for your ribbon controls instead of adding new elements at runtime.
The IRibbonUI.Invalidate method invalidates the cached values for all of the controls of the Ribbon user interface.
You can customize the Ribbon UI by using callback procedures in COM add-ins. For each of the callbacks that the add-in implements, the responses are cached.
For example, if an add-in writer implements the getImage callback procedure for a button, the function is called once, the image loads, and then if the image needs to be updated, the cached image is used instead of recalling the procedure. This process remains in place until the add-in signals that the cached values are invalid by using the Invalidate method, at which time, the callback procedure is again called and the return response is cached. The add-in can then force an immediate update of the UI by calling the Refresh method.
<customUI … OnLoad="MyAddinInitialize" …>
Dim MyRibbon As IRibbonUI
Sub MyAddInInitialize(Ribbon As IRibbonUI)
Set MyRibbon = Ribbon
End Sub
Sub myFunction()
MyRibbon.Invalidate() ' Invalidates the caches of all of this add-in's controls
End Sub
The Fluent UI is described in-depth in the following articles:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)
Also, you may find the Walkthrough: Create a custom tab by using Ribbon XML helpful. Note, you can export an existing custom ribbon UI to the XML and continue dealing with a raw markup.

Is this a way to show a modeless dialog from a dockable pane using WPF?

I'm building a Revit plugin. It consists of a dockable pane that (among other elements) has a button. I want to open a new, separate window when a user clicks this button.
At the moment, i create a new Window, but i don't know if that's the right way to go, because now i see two Revit icons on a task bar. I do not have experience as Revit user, i'm new to Revit development, so i'm not sure if this should be the case (two icons) and as silly as it sounds, i do not have admin rights to install random addins and get a feeling of expected user experience.
I create a Window using the following code:
ParametersMissingValueWindow parametersMissingValueWindow = new ParametersMissingValueWindow();
parametersMissingValueWindow.Show();
Based on the understanding of a dockable pane that i have, i think i do not want to create another dockable pane, but just a simple modeless dialog. I wasn't able to find any examples using WPF. Hence, any information whether this is the way to go or help on how to achieve this is highly appreciated.
The Show method takes an optional parent window argument. Specify the Revit main window as the parent window, and your modeless dialogue will be recognised as belonging to the running Revit process. It is accessible from the MainWindowHandle property.
var MyWindow = new MyWindow();
HwndSource hwndSource = HwndSource.FromHwnd(UIApplication.MainWindowHandle);
Window wnd = hwndSource.RootVisual as Window;
if (wnd != null)
{
MyWindow.Owner = wnd;
//MyWindow.ShowInTaskbar = false;
MyWindow.Show();
}
It's not necessary to assign a value to ShowInTaskbar property, but it actually achieves what i wanted to do from the beginning (have only one program open in taskbar), so i left it as part of the solution, but commentted out.
Big thanks to Jeremy Tammik for pointing out the parent property.
You can use WPF to setup a window to use in revit.
MyWPF menu = new menu();
System.Windows.Window wind = new System.Windows.Window();
wind.ShowDialog(); //--> the window shows up and make stuff for revit
if you need the menu to be a dockable one check this source.
Perhaps is not up to date and you will need to adapt the code to the new api.

Adding CustomTaskPane without pane options

I have a CustomTaskPane in Outlook which I'm adding with following code in C#:
var pane = Globals.TrackingAddIn.CustomTaskPanes.Add(new MyControl(), " ");
pane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
pane.Width = 700;
And in Outlook it looks like this:
Current layout
Is it possible to hide buttons marked in red (pane options and close?) I tried setting negative margin to the control and various values of DockPositionRestrict, but it doesn't change anything. I'd like my control to be shown immediately below the ribbon.
No, the buttons cannot be hidden.
If we are talking about Custom Task Panes - there is no trivial way to hide thease controls.
But instead of using custom task panes you may consider using Advanced Outlook Form Regions. Or just use Windows API for subclassing Outlook windows, see Adjacent Windows In Outlook for more information. The Creating Adjacent Windows In Outlook sample code in C++ is available.

Custom Task Pane Office(Excel) many times slide to open on Excel 2013

I created my own Excel Addin and after clicking the button displays a Custom Task Pane on right. Everything is fine but when I run this addin in Excel 2013. This displays Custom Task Panes with slide it open.For my Addin Flashes disappear and appear. It looks like a problem with the display.
Is there any solution? It looks very, very wrong.
PS. I'm sure they do not Set Custom Task Panes instance twice.
Display and hide performed using xxxxxxx.Visible = true / false;
Slide to close is Ok.
-------ThisAddIn.cs
_calcTaskPaneControl = new UI.CalcTaskPane();
_calcTaskPaneValue = this.CustomTaskPanes.Add(_calcTaskPaneControl, Common.CommonFunctions.GetLocalizeText("ThisAddIn_CalcTaskPaneTitle"));
_calcTaskPaneValue.VisibleChanged += new EventHandler(CalcTaskPaneValue_VisibleChanged);
--------MainRibbon.cs
Globals.ThisAddIn.CalcTaskPane.Visible = true;
I've noticed the same with Excel 2013. Whenever you set the visibility or the width, Excel 2013 reloads the taskpane. I had to updated all places to check if the CustomTaskPane not already is visible or invisible before setting it. So when your CTP is visible and you set Visible to True again, it will reload the taskpane. Excel 2010 doesn't do this.

c# Excel - Display ribbon on exit

I'm using VSTO to design an application with an Excel interface. I want to hide the ribbon on startup (shouldn't be needed in the application) and re-display it on exit (if the user had it originally displayed), to avoid irritating people who use the application and want a ribbon the next time they open Excel.
I can hide the ribbon using essentially the following code in ThisWorkbook_Startup (from this question Excel 2007 Minimize the Ribbon programatically but Not the menu bar):
Office.CommandBars cbs = null;
cbs = Application.CommandBars;
foreach (Office.CommandBar commandBar in cbs)
{
if (commandBar.Name == "Ribbon")
{
this.Application.ActiveWindow.Activate();
Application.SendKeys("^{F1}", true);
}
}
However, the same code or similar variations from the previously referenced question do not seem to work when placed in either the ThisWorkbook_Shutdown or ThisWorkbook_BeforeClose methods. The code is hit but never seems to execute - the ribbon is never restored.
Is there another way to restore the ribbon on exit?
Thanks,
Andrew

Categories