Visio VSTO: InvalidateControl not working on focus change

199 Views Asked by At

Using Visio 2013 I faced a strange behaviour of InvalidateControl method (or Visio VSTO mechanism). My idea is to change selected item in dropDown1 whenever I change its item value in editBox1.

It works when I change text and hit Enter or click on free area on ribbon tab, but in does not work if I click on editBox2 making it active (focused). In the latter case DropDown gets updated (and callbacks get called) only if I click on DropDown itself afterwards.

I've also noticed that DropDown gets updated whenever Visio window loses focus ang gains it again (for instance if I switch to another aplication and back), so my other hacky idea was to force Visio to update its UI in some way (for instance via WinAPI like RedrawWindow etc), unfortunaly I don't know well all the stuff with WinAPI.

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
  <ribbon>
    <tabs>
      <tab idMso="TabAddIns">
        <group id="group3" label="Test">
          <box id="box1">
            <editBox id="editBox1"
                     getText="GetText"
                     onChange="EditBoxTextChange"
                     sizeString="WWW" />
            <editBox id="editBox2"
                     getText="GetText"
                     sizeString="WWW" />
            <dropDown id="dropDown1"
                      getSelectedItemIndex="GetSelectedItemIndex"
                      getItemCount="GetItemCount"
                      getItemLabel="GetItemLabel"
                      sizeString="WWW" />
          </box>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

Ribbon class

public class Ribbon1 : Office.IRibbonExtensibility
    {
        private Office.IRibbonUI ribbon;

        string[] data = { "1", "2", "3", "4", "5" };
        int selectedIndex;

        public Ribbon1()
        {
        }

        #region IRibbonExtensibility Members

        public string GetCustomUI(string ribbonID)
        {
            return GetResourceText("FosusTest.Ribbon1.xml");
        }

        #endregion

        #region Ribbon Callbacks
        //Create callback methods here. For more information about adding callback methods, visit http://go.microsoft.com/fwlink/?LinkID=271226

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

        public string GetText(IRibbonControl control)
        {
            if (control.Id == "editBox1")
            {
                return "1";
            }
            else
            {
                return "2";
            }
        }

        public void EditBoxTextChange(IRibbonControl control, string text)
        {
            for (var i = 0; i < data.Count(); ++i)
            {
                if (data[i] == text)
                {
                    selectedIndex = i;
                    ribbon.InvalidateControl("dropDown1");
                    break;
                }
            }
        }

        public int GetSelectedItemIndex(IRibbonControl control)
        {
            return selectedIndex;
        }

        public int GetItemCount(IRibbonControl control)
        {
            return data.Count();
        }

        public string GetItemLabel(IRibbonControl control, int index)
        {
            return data[index];
        }

        #endregion

    }

Example project Visual Studio 2013 / Visio 2013

1

There are 1 best solutions below

1
Nikolay On

May it be some issue with a specific Visio version (2013)? For me, everything seems to work properly (the combobox changes, when you change focus from edit1 to edit2)? This is the latest Visio (16.0.13127):

enter image description here

If it does not work only with 2013, I would try service packs :) I.e. the code itself looks okay, there is nothing wrong with it.

If you really-really need a "hacky" workaround for that specific version, I would try subscribing to VisioIsIdle event, and updating there.