We’ve recently started using the Silverlight 5 PivotViewer control in On Key Express as a great way for visualizing the Work Orders showing the work list that needs to be completed/has been completed. Here is some screenshots showing the different “cards” of information for the Work Orders at different zoom levels.
Small Card View
Large Card View
One of the great features of On Key Express is the ability for clients to translate the system into any language. This is great feature for customers who have engineers working across the globe as they can customise the system into any language they which to support. We supply the default English translation but the clients can even decide to change the English translation if they have certain client specific terminology they want to use.
This language feature however imposes an important restriction of any third party control that we use – we need the ability to translate any resource displayed by the control. We make extensive use of the excellent Telerik RadControls for Silverlight. Fortunately these controls are fully localizable by hooking up a custom ResourceManager to override the default resources being used by the Grids and other controls.
The PivotViewer control has quite a few resources. It ships with support for a few languages out-of-the-box through providing the resources in separate System.Windows.Controls.Pivot.resources.dll resource assemblies. By setting the ItemCulture property you are able to use the different out-of-the-box translations shipped with the control. However, unlike the Telerik controls there is however no easy way to hook into the control to override the resources being used. We can create additional resources assemblies for different languages but as mentioned previously, the client decides what additional languages they want to support.
We therefore needed a way to hook into the PivotViewer to inject our own Resource Provider that will use the client provided resource translations. Technically we store the clients translations in a database that is periodically synchronised with the client devices. After looking at the PivotViewer using Reflector, we confirmed that it makes use of the usual an internal static Resources class that is generated whenever you add .resx files to a project. The Resources wrapper internally makes use of a ResourceManager that uses the current culture to access the language specific resource file. We needed the ability to intercept the calls being made by this ResourceManager. We also wanted the ability to still use the existing Microsoft resource assembly as the default fallback mechanism for any of the resources that we don’t want the clients to translate. There includes the numerous exceptions and other design time resources which the clients aren’t interested in.
With this in mind, we created the following PivotViewerResourceManager wrapper class:
Notice that the class is a simple ResourceManager wrapper around the existing Microsoft resource assembly. When override the GetString method to allow us to first do an external lookup for the resource using our IResourceProvider interface. If we do not have an external translation, we simply delegate to the Microsoft provided resource. We adopted the convention of prefixing all the client provided translations for the PivotViewer with the “MSPivot” prefix as it makes it easier to identify all the translations related directly to the control. With all of this in place we simply added a trigger to the PivotViewer XAML to load and inject our PivotViewerResourceManager when the control is loaded via the InjectResourceManager method.
Here is a sample screen shot of our ResourceManager in action with the PivotViewer. Notice that some of the resources for which we provide translations are show in a different language whilst the rest of the control falls back to using the default MS provider resources.