Another week and another customer. I have a customer that I built a Outlook plugin for that displays active CRM data. The challenge this weekend was to provide a more updated UI experience with theme switching. There were several hurdles I had to overcome to the current design and problems to solve. To accomplish this task I had to resolve the following
- Determine the color settings for each theme in outlook and build the appropiate .xaml resource dictionary for the matching theme
- Theme the controls, extracting templates and updating the resources to point to the custom colors/fonts
- Reconfigure each of the UI components to use the theme files
- Create a theme service/switcher to change the themes dynamically
- Create a service to determine when outlook changes a theme
- Test and enjoy a donut and coffee
For determining the colors required I took a brute force method. Switching to each theme in outlook, taking a snapshot image and using Gimp to extract the required component colors. There were 4 themes that I attacked Dark, White, DarkGray and Colorful. It did not take long to extract the colors.
For each of the controls such as DatePicker, Combobox, ListBox .. etc I extracted a copy of the style template. I then updated the colors and fonts using the new resources I created. This took some time and tweaking to make sure that rendering was not broken.
The project had many Controls, Panels and Dialogs, each had to be updated to point to the new resource dictionaries. This was not much problem however depending on the location of the resources I had to update the source uri’s appropriately. In the end it work as expected
The interesting part of theme switching was about how the resources were added to the underlying components. Theme switching constitutes replacing one ResourceDictionary for another. For my case I just ensured that the style dictionary was in position 0 in the underlying component’s merged dictionaries. Basically just:
userControl.Resources.MergedDictionaries.RemoveAt(0);
userControl.Resources.MergedDictionaries.Insert(0, resourceDictionary);
I did find have an initial issue as I was not seeing my active changes however when I updated my components to use DynamicResource instead of StaticResource the UI updated correctly.
Digging around the internet to find out if VSTO provided any kind of notification for theme switching led me to an answer of NO. So I kept researching and found out that when Office updates the theme it writes the value to the registry. Given that I could poll the registry for changes I wrote a service to read the UI Theme value and on a change published an event to the outlook plugin. Once the event notification was received the theme switcher updated each of the UI components.
I was successful this weekend in updating plugin to use theming, and added a level of polish and professionalism that I believe my client will appreciate.