Hi,
I'm experimenting with changing colors in the new Office 2013 theme in version 14.1. I'm using the Infragistics Color Tuner from within Visual Studio.
For most controls, everything works as expected, but the Ribbon does not seem to act upon changes to the colors. The attached zip file shows two examples of the Ribbon being 'washed' with a green color.
As the ribbon1.jpg image shows, the Ribbon still uses the default blue base color.
The ribbon2.jpg shows another strage effect in that parts of the ComboEditorTool uses the default, blue color while other parts (the expanded part) uses the green color I supplied.
In addition to making modifications to my existing application I also tried this on a simple sample application, but with the same effect; The ribbon is not correctly 'washed' with the changed colors. Are the changes made by the Infragistics Color Tuner not sufficient for modifying the Ribbon, and are additional steps required ? What am I doing wrong ?
Regards,Leif
Hi Leif,
It's hard for me to tell from your images exactly how you are incorporating the ResourceWasher into you application.
There is a very good sample in the Feature Browser to give you some idea about the impact of using the washer. Look in the XamRibbon in the Style section for Live ResourceWasher. It allows you to change the base theme and the WashMode as well as change the single wash color you are using.
I took a xamRibbon sample that I have and removed any reference to Theme on the controls. Then I added the ResourceWasher to the Application’s ResourceDictionary in MergedDictionaries.
You need to add a namespace to your app.xaml file for the Themes.
xmlns:igThemes=http://infragistics.com/Themes
Then you can add the ResourceWasher and modify as you need.
<ResourceDictionary.MergedDictionaries>
<igThemes:RibbonOffice2013 />
<igThemes:ResourceWasher AutoWash="True" WashColor="#FF76923C" WashMode="HueSaturationReplacement" >
<igThemes:ResourceWasher.SourceDictionary>
<igThemes:RibbonWashBaseLight />
</igThemes:ResourceWasher.SourceDictionary>
</igThemes:ResourceWasher>
</ResourceDictionary.MergedDictionaries>
Please let me know if you have any questions.
your sample helped me. It looks like my error was caused by the fact that I also explicitly set the Ribbon's theme in XAML, e.g. specifying Theme="Office2013" in the XamRibbon XAML element. Removing this XAML attribute makes the colors look as expected.
However, removing the 'Theme' attribute from the XAML and using the resource washed theme instead, now gives another issue: I'm using custom code to add an item to the Ribbon's context menu. The code to do this is called from the Ribbon's 'Loaded' event handler, and basically look like this:
var contextStyle = this.ribbon.FindResource(typeof(RibbonContextMenu)) as Style;if (contextStyle == null){ return;}contextStyle.Setters.Add(new EventSetter{ Event = ContextMenu.OpenedEvent, Handler = new RoutedEventHandler(this.ContextMenuOpened)});
The 'ContextMenuOpened method does the actual adding of the menu item.
Previously, and when Theme="Office2013" was specified for the Ribbon, everything worked fine. Now, after removing the 'Theme' attribute and using the resource washing feature, I get an InvalidOperationException in the code above, when calling the 'Setters.Add' method. The additional message of the exception is:"After a SetterBaseCollection is in use (sealed) it cannot be modified".
Additionally, when I now arrive to this point of code the Setters collection is empty. Previously it had 6 items.
Obviously, using resource washing affects parts of the Ribbon's setup in a way that breaks my code. How can I rewrite my code to make the menu item adding work when using resource washing ?
I'm attaching my sample. I added the explicit theme and the wash in the App resourceDictionary Merged Dictionaries.
And I added the ContextMenuOpening event to the XamRibbon in the XamRibbon's loaded event.
Take a look at my code and let me know if this helps.
if I run your sample, the xamRibbon1_ContextMenuOpening method is only called when right-clicking a small part of the Ribbon. See the attached image. Right-clicking the Ribbon only calls the ContextMenuOpening event code for the parts of the Ribbon that is marked red in the attached picture.
Additionally, if I change your sample by wrapping the Ribbon in a XamRibbonWindow (like I do in my application), the xamRibbon1_ContextMenuOpening method is never called.
Let me first talk about the xamRibbon, not in a XamRibbonWindow. The contextmenu of the xamRibbon would only be accessible from the xamRibbon, not from the ApplicationMenu or the QAT. The Application Menu appears in the upper left corner of the ribbon. The QAT is currently in the left hand corner of the ribbon caption area; it can repositioned below the ribbon. They have their own Customized Quick Access Toolbar and Application toolbar menues. So you should only expect the contentmenu of the XamRibbon event to fire from the area you have marked as red in your image.
You could customize the Application Menu or the Quick Access Toolbar by adding tools if that would be helpful.
http://help.infragistics.com/doc/WPF/2014.1/CLR4.0/?page=xamRibbon_Application_Menu.html
http://help.infragistics.com/doc/WPF/2014.1/CLR4.0/?page=xamRibbon_Quick_Access_Toolbar.html
As for a XamRibbon hosted in a XamRibbonWindow it is displayed within the caption area (non-client area) of the xamRibbonWindow. The window chrome is now accessible by the application.
This link may help explain. http://help.infragistics.com/doc/WPF/2014.1/CLR4.0/?page=InfragisticsWPF4.Ribbon.v14.1~Infragistics.Windows.Ribbon.RibbonWindowContentHost.html
I've never discussed the Application Menu or the QAT, and I know how to use them.
I want to add a 'Customize Ribbon' item to the context menu that is accessible from almost anywhere else in a normal Ribbon. Your statement that this should only be accessible from the area I marked as red in the figure is wrong: All Micrososft Office applications e.g. have a context menu with a 'Customize the Ribbon...' menu item and this menu is available in e.g. all the tabbed panels in the Ribbon. The Infragistics Ribbon has also worked that way, and I have got my corresponding customization code to work on all versions (including 14.1) if I explicitly set the Ribbon theme. The change to use an implicit theme has obviously changed/broken something in the internal Ribbon handling. How to fix this?
I believe I finally understand your reference. Your thread is on a WPF forum and the feature you are asking about is for the Silverlight XamRibbon.
Here is a link to our documentation concerning using the Ribbon Customization Dialog.
http://help.infragistics.com/doc/Silverlight/2014.1/CLR4.0/?page=xamRibbon_Using_Ribbon_Customization_Dialog.html
Please let me know if this answers your question.
I contacted our developers for their explanation and recommendation. What you are trying doesn’t work for a few reasons.
An exception happens because you cannot change a Style that has been sealed. You’ll notice that even if you don’t set the Theme and don’t have any resources in the App.Resources for the ribbon the Style you get from the FindResource is sealed. That Style would be the default style for the control and the framework seals that because it is shared across all instances of the control which may be on different threads.
As for having resources for the XamRibbon in the App.Resources, it seems there is a bug in the WPF framework because the FindResource seems to still return the default style. Calling the FindResource a second time seems to get the resource from the App.Resources. However, the framework still freezes resources added to the App.Resources so an exception would still be thrown.
The suggest for you is to register a static event handler for the Opened event of the RibbonContextMenu ( since it is a RoutedEvent ) and handle the event that way.
public partial class MainWindow : Window
{
static MainWindow()
EventManager.RegisterClassHandler(typeof(RibbonContextMenu), RibbonContextMenu.OpenedEvent,
new RoutedEventHandler((o, e) =>
var cm = o as RibbonContextMenu;
var ribbon = XamRibbon.GetRibbon(cm);
var window = ribbon != null ? Window.GetWindow(ribbon) : null;
if (window is MainWindow)
((MainWindow)window).ContextMenuOpened(o, e);
}));
}
Registering the event this way allows you to add the Theme and the Wash as I originally suggested in the App.xaml. And you can dispense with your logic in the Loaded event.
Let me know if you have any questions.
I guess I can live with this solution.
As for having resources for the XamRibbon in the App.Resources, it seems there is a bug in the WPF framework because the FindResource seems to return the default style. Calling the FindResource a second time seems to get the resource from the App.Resources. However, the framework still freezes resources added to the App.Resources so an exception would still be thrown.
this workaround works fine in my main application as well. However, it would be nice to know if this is a bug, especially since any further use of the Infragistics Color Tuner will put the corresponding code back into App.xaml.
I have found that if you add the MergedDictionaries, the Theme and the ResourceWasher, directly to the XamRibbon instead of in the app.xaml that solves the issue you were having.
<igRibbon:XamRibbon.Resources>
<ResourceDictionary>
</ResourceDictionary>
</igRibbon:XamRibbon.Resources>
I'm looking into the explanation for this behavior.