I'm trying to understand some of the behaviors I'm experiencing in my custom outlook VSTO ribbon and the main difficulties I'm facing are tied to what seems to be a single instance of the ribbon being shared among concurrently open inspector windows (my custom ribbon is displayed for ribbon type "Microsoft.Outlook.Mail.Compose"). Is there indeed a single instance of the ribbon being shared among potentially multiple instances of inspect windows? If so, how do you handle concurrent different states in the different inspector windows?
What you do is create the one custom Ribbon and from each view you handle the items in the Ribbon that you need. Here is a question that somewhat relates to your question:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/57dc20bb-9d29-4d3e-84d2-c64de0af0244/iribbonextensibilitygetcustomui?forum=vsto
In your case you want to maintain state, that is using the same paradigm. Whenever you get focus on the composing mail you make sure the state of the Ribbon matches the state of the composing mail.
By doing so the one time loading of the Ribbon XML is no longer an issue as you have all items in one Ribbon and are able to manipulate the state for each of the composed mails.
Related
I have two buttons which I've added to the Quick Access Toolbar (QAT) in MS Word, both of which are linked to macros written in a module. I want the second button to be greyed out (or locked) until the first one has successfully run, at which point I will unlock in the code.
How do I access the button objects with vba? I'm looking for something along the lines of ActiveDocument.QATButton1.Locked = True. With a standard Active X button you can right click and view properties to get the button name but I can't seem to do this with these (they were created via Options>QAT>Macros>Add)
If you want to disable or enable your Fluent UI controls (QAT) dynamically you need to use ribbon callbacks with IRibbonUI.Invalidate or IRibbonUI.InvalidateControl methods. For each of the callbacks that the custom UI implements, the responses are cached.
For example, if an add-in writer implements the getEnabled callback procedure for a button, the function is called once, the state loads, and then if the state needs to be updated, the cached state 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.
You may find the Ribbon UI (aka Fluent UI) described in depth in the following series of 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)
I am building an Outlook Add-In in Visual Basic and I have a togglebutton in the ribbon that controls whether a setting is on or off. This settings is saved and retrieved using "GetSettings" and "SaveSetting" which saves information to the Windows Registry (to my understanding). I want the togglebutton the correspond to changes made to that setting as it can be changed in other places than just the togglebutton. My problem would be solved if I could access the value of the togglebutton and setting it manually but as I have understood it: I cannot access it as I am building my ribbon in XML. I have not been able to find a solution to this, can anyone help?
Side note: If I add my togglebutton to the taskbar in Outlook and from there toggle the settings, the togglebutton in the ribbon doesn't change to "pressed" mode. Perhaps this is something that can be fixed with any provided solution from anyone :)
You need to use IRibbonUI.Invalidate or for a single control you may use the IRibbonUI.InvalidateControl method to get your ribbon callbacks invoked for updating the cached values according to the state loaded from settings.
For example, if an add-in implements the getPressed callback procedure for a toggle button, the function is called once, the state loads, and then if the state needs to be updated, the cached state 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 (VSTO).
You can read more about the Fluent UI (aka Ribbon UI) 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)
Do not rely on the button to store the state for you - whenever it changes, it is your responsibility to refresh the Ribbon (by calling IRibbonUI.Invalidate), which will cause Outlook to invoke your callback on the toggle button to determine its state. You just need to store the appropriate state in your code.
I have a some VBA that will file an outgoing message as a Task (and do some other things) if I tag it. One way I tag is by calling a macro that sets a UserProperty; I have assigned the macro to a button on the command bar.
I would like to visually mark the message as having been tagged before I send it, and then implement a toggle, but I'm struggling to find a way of doing it. So keeping the button depressed, or highlighted, would work but I can't see how to do this in the Fluent UI stuff. Alternatively, I'd like to add something to the area to the right of the "pop out" "discard" buttons at the top of the message.
I tried adding a category to the new message, but this is not displayed in the pane. I do have a UserProperty assigned, but I don't know how to display that either.
Any ideas?
Many thanks
VBA doesn't allow customizing the Fluent UI. You need to develop a COM add-in instead. To implement a toggle button on the Ribbon you need to define callbacks where you may check the user property value and update the UI accordingly. The Fluent UI is described in-depth in the following series of 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)
I'm using VSTO with VB.NET for Excel 2013. I'm developing an application-level add-in, but I can't make two different workbooks store different "ribbon state". For example, when I want to enable a button, I use the following code:
Globals.Ribbons.Ribbon1.myButton.Enable = False
This makes the element "myButton" to be disabled on each opened workbook, but I want to make it disabled only for one workbook.
The way I'm doing now is to handle the event WorkbookActivate, to change the ribbon state. The problem is: this way, the user sees an invalid state at other workbooks that are not on the top.
There is some better workaround? There isn't a way to manage the ribbon instances (and not only the global element as I am doing)?
Thanks
There is some better workaround? There isn't a way to manage the ribbon instances (and not only the global element as I am doing)?
You need to use callbacks instead. Try to use the getEnabled callback instead.
Moreover, when required you can use the IRibbonUI interface methods to force Office applications to update the UI controls. The Invalidate method invalidates the cached values for all of the controls of the Ribbon user interface. See Overview of the IRibbonUI Object .
You can read more about the Ribbon UI (aka Fluent UI) in the following series of articles in MSDN:
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)
I'm working on outlook 2007 VSTO Addin.I have added a Ribbon with a button. I am trying to raise an event on button click.On NewInspector event of Application.Inspectors collection I should be able to hook on to this ribbon event in the Presenter.
The questions is how to get hold of Ribbon of Inspector opened. I tried Globals.Ribbons.MyRibbon to do so.Strangely it works only for the first inspector. I also tried Globals.Ribbons[inspector].MyRibbon.
Looks like when NewInspector is created the Ribbons Collection has 0 Items and Ribbon load happen only after NewInspector event handler is executed.
Is there any event to know when a ribbon loads OR Is there any alternative way ,where i can keep the business logic in Presenter instead of having it in ribbon view.
The answer is with much effort..
As far as I can tell the ribbon is not exposed through vsto or com interop, it is also stateless, so the ribbon will be loaded once no matter how many inspectors are shown.
It took me a long time to gracefully solve this issue, and it is pretty complex code. I also should mention that I chose to tackle the problem using ribbon XML rather than the designer, I found the designer too restrictive.
The guts of it is you have to create a custom IRibbonExtensibility implementation, then rewrite the callbacks in the ribbon XML, so they will callback to methods on your IRibbonExtensibility impl.
You then have to handle the loaded event, and the new inspector event so you can relate the two.
There is actually a lot more to it and you can check out my code in the VSTO contrib project.
http://vstocontrib.codeplex.com/SourceControl/changeset/view/b35f26fdca15#src%2fOutlook.Utility%2fRibbonFactory%2fRibbonFactory.cs
If you are building a MVP framework for VSTO drop me an line as I would be interested to see what you are doing.