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 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.
No, I am not asking about the Silverlight XamRibbon, I am using WPF. I have implemented the WPF Ribbon customization dialog myself. I just want to add a generic context menu item to the WPF Ribbon context menu to launch my custom dialog. And as mentioned, this used to work perfectly for several years.
/Leif
You mentioned that this used to work. Could you provide a small sample with your customization dialog working and I'll try to see if I can determine how to make it work using 2014.1.
I pretty much posted my previously working code in my second post, but I attach a modified version of your sample. Look for the two '#if CHANGES_BY_LEIF' blocks in MainWindow.xaml.cs. The code as it is throws an exception as I described in my second post. If you modify MainWindow.xaml by adding a 'Theme=Office2013' attribute to the XamRibbon element, the code works fine and adds an 'Added Item' item to the Ribbon's context menu. The added item is available in the context menu that is launced at all locations in the Ribbon (i.e. not only in the red area of the previously attached picture).
Of course, when I add the 'Theme=Office2013' attribute, the resource washing does not work, which is why I wrote my original post.
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.
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.