Changing the value of an editBox office Ribbon Control at runtime

When creating VSTO Add-Ins that customize the Office Ribbon, the visual Ribbon editor makes some tasks trivial. All Ribbbon controls can be accessed by id using intellisense. The RibbonEditBox.Text field can be directly queried and modified.
Everything changes when you create the RibbonXML directly.

You cannot directly query any of the runtime values on a ribbon control. You must use the OnChange callback to get the value in the box.

        public void OnChange(Office.IRibbonControl control, string text)
        {
        }

But what if you wanted to change the value of the editBox (aka change the text)? Say perform some validation, or formatting?

I tried casting the IRibbonControl object supplied by the callback to a RibbonEditBox object… This didn’t work.
I tried casting the control object as a Dynamic and accessing the “Text” property… No dice.
I looked for some means of getting the ribbon control so I could modify the Text value – nothing.

The solution:
(Which was surprisingly difficult to find)
There are three things you will need to do:
1. Within your ribbon’s class, make sure you are saving the IRibbonUI reference provided by Ribbon_Load to a private variable. I just call it “ribbon”
2. Implement the getText callback and a private string variable to hold the internal value for the editBox
3. Implement the onChange callback to perform validation, update the private variable, and use the IRibbonUI object to invalidate the editBox control. This triggers the ribbon to call the getText callback again, effectively updating the field.

An example:
This snippet when merged into the Ribbon class, will ensure that the text entered in an edit box ends with “of doom”

First, the ribbonxml part

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
  <ribbon>
    <tabs>
      <tab id="DoomedObjects" label="DoomedObjects">
        <group id="spg" label="Stuff">
          <editBox id="txtDoomed" label="Doomed" onChange="OnChange" getText="GetText"/>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

And the c# for the Ribbon class

        private string textValue;
        private Microsoft.Office.Core.IRibbonUI ribbon;


        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            this.ribbon = ribbonUI;
            textValue= "";
        }

        public void OnChange(Office.IRibbonControl control, string text)
        {
            if (!text.EndsWith("of doom"))
            {
                textValue = text + " of doom";
                ribbon.InvalidateControl(control.Id);
                //Only invalidating when the value needs to change. You could invalidate after the if block as well 
            }
            else
            {
                textValue = text;
            }
        }

        public string GetText(Office.IRibbonControl control)
        {
            return textValue;
        }


Behaviour of Application.MailMergeAfterRecordMerge Event

The signature for the Application.MailMergeAfterRecordMerge event looks like this:

        void Application_MailMergeAfterRecordMerge(Word.Document Doc)
        {
        }

While I would have expected the Document referenced in the Doc parameter to be the newly created merged document, it is actually a reference to the document from which the merge occurred. In other words, it’s not really all that useful.

Automate Word Mailmerge Preview Results

(Long story short: the property you need is ViewMailMergeFieldCodes. Set it to 0 to enable preview; -1 to disable preview)

The mail merge process in Microsoft Word is a bit of a bear to automate sometimes. I suppose I should be thankful that it can be automated at all, but there are bits of it that are very poorly documented, requring a bit of trial and error to work with. It doesn’t help that most Office interop documentation leans toward Visual Basic…

Anyway, today’s issue was attempting to programmatically Preview the results of a Mail Merge in a C# VSTO project, like the button in the ribbon:

Big surprise: Document.MailMerge doesn’t contain any properties or methods with the word “preview”

Turns out there is a property called ViewMailMergeFieldCodes that does what we need, but in reverse. Microsoft’s documentation states:

This property returns True if merge field names are displayed in a mail merge main document, and False if information from the current data record is displayed

Trouble is, the field is an int, not a bool! A little debugging to the rescue:
When this field is set to -1, Preview is disabled, and the field codes are displayed.
When set to 0, Preview is enabled, and the record data is displayed.

To switch the displayed record, change Document.MailMerge.DataSource.ActiveRecord.

Now if only there was an event that fired when the record changed…