Introduction to Resource Washing in NetAdvantage for Silverlight 11.2

Damyan Petev / Thursday, November 3, 2011

The Resource Washer is a XAML cross-platform component. It has no visual representation, yet its features are about looks – it provides an fast and easy way to ‘wash’ a ResourceDictionary with one or multiple colours for possibly quite dramatic end results. It allows to set the colour of a resource by specifying a new one and colour transformation that is applied.

Provide it with a resource dictionary and it will let you modify the overall colour scheme of the application. The way it functions is not changing the original brushes/colours but rather making a copy of the dictionary and then changing the copy according to the defined settings.  And this happens in runtime without actually modifying the original dictionary. A resource dictionary contains a collection of keyed sharable objects used by components in the application such as styles, templates, colours, brushes and so on. And washing is a process that changes the colours with new ones that are the result of the colour transformation chosen.

The component started as WPF tool and has now been ported to Silverlight  and in Release 11.2 introduced as a proper stand-alone XAML cross-platform component. And while both Silverlight and WPF use ResourceDictionary there are some differences you can read about here.

The wash modes

The Resource Washer provides two modes (colour transformations) you can set along with a desired colour:

  • SoftLightBlend – this is the default mode and what it does is blending each of the RGB with the wash colour ones. The best way to actually explain the process it actually imagining  washing clothes in coloured  water. Or even better – a visual demonstration:

Here we have two Borders with backgrounds using LinearGradientBrush. In their original settings they look like that:

And after washing the dictionary that contains those backgrounds with red in runtime they change to:

As you can see every colour has picked some red, some more than others, but the colour palette has been modified.

  • HueSaturationReplacement – this is the mode to use when setting a dominant colour is not enough and the idea is to have a single one. As its name suggests this mode will replace both the hue and the saturation of the original colours with the wash one while keeping just the brightness value.

The same two Borders as above:

This time washed with cyan:

Using the Resource Washer

First thing is of course adding the component to the application starting with a reference and namespace. The Resource washer is in the base Silverlight assembly - InfragisticsSL4.v11.2.dll and also required is:

  1. xmlns:ig="http://schemas.infragistics.com/xaml"

Then depending on the scope you would need you can reference the component as a resource (e.g. in the UserControl). The basic settings can be done in both XAML and in code. The properties are pretty self-explanatory -  WashColor , WashMode, and AutoWash (automatic or manual washing). There’s one more major property – setting a SourceDictionary. Done in XAML with automatic wash it would look like:

  1. <UserControl.Resources>
  2.     <ig:ResourceWasher x:Key="resWash" AutoWash="True" WashMode="SoftLightBlend" WashColor="Azure">
  3.         <ig:ResourceWasher.SourceDictionary>
  4.             <ResourceDictionary Source="Styles.xaml"/>
  5.         </ig:ResourceWasher.SourceDictionary>
  6.     </ig:ResourceWasher>
  7. </UserControl.Resources>

The benefit of being able to set things up in code comes when making the wash interactive because the example above has AutoWash on and a WashColor defined which means the resources in styles.xaml will be washed with the application launch and the originals will never be seen. As expected the component properties have default values and the default value for WashColor is actually transparent that doesn’t really produce any results at all. So at this point there are two really good opportunities to handle events to execute a wash:

  • Set the AutoWash to false and call the Resource Washer’s WashResources() method an event handler:
  1. using Infragistics;
  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3.     ResourceWasher resWash = (ResourceWasher)this.Resources;
  4.     resWash.SourceDictionary = Application.Current.Resources;
  5.     resWash.WashResources();
  6. }
  • Don’t define WashColor to begin with and skip AutoWash too (its default it true). Then define a WashColor inside an event handler and the Resource Washer will pick it up and automatically alter the resources with it:
  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3.     ResourceWasher resWash = (ResourceWasher)this.Resources;
  4.     resWash.WashMode = WashMode.HueSaturationReplacement;
  5.     resWash.WashColor = Colors.Cyan;
  6. }

Additional Customization

  • Attached properties

There’s something very useful that can be found in the ResourceDictionary inside Styles.xaml used above:

  1. <ResourceDictionary
  2.     ...
  3.     xmlns:ig="http://schemas.infragistics.com/xaml">
  4.        <SolidColorBrush x:Key="ReallySolid" Color="DarkGray" ig:ResourceWasher.IsExcludedFromWash="True"/>
  5.     ...
  6. </ResourceDictionary>

The Resource Washer adds two attached properties to Brushes, one of which when set to true excludes them from the wash and any part of the application that uses them will be unaffected after a wash.

The other property is assigning Brushes to groups:

  1. <SolidColorBrush x:Key="grp1" ig:ResourceWasher.WashGroup="WashGrp1" Color="Coral"/>

Those groups can then be added to the Resource Washer’s WashGroupCollection  and this allows to wash different elements with different wash settings:

  1. <ig:ResourceWasher x:Key="resWasher">
  2.     <ig:ResourceWasher.WashGroups>
  3.         <ig:WashGroupCollection>
  4.             <!--This group will be washed in Blue instead and in HueSaturationRelacement mode-->
  5.             <ig:WashGroup Name="WashGrp1" WashColor="AliceBlue" WashMode="HueSaturationReplacement" />
  6.             <!--This group will be washed in Magenta and with the default mode-->
  7.             <ig:WashGroup Name="WashGrp2" WashColor="Magenta"/>
  8.             <!--This group will be washed in default colour(black) and mode-->
  9.             <ig:WashGroup Name="WashGrp3"/>
  10.         </ig:WashGroupCollection>
  11.     </ig:ResourceWasher.WashGroups>
  12. </ig:ResourceWasher>

Conclusion

The benefit of using the Resource Washer go beyond being ale to change a few colours, the best part is actually taking a control with complicated styling like a xamGrid and wash all it’s colour to your liking in runtime and to make it even better combined with xamColorPicker it can provide  great end-user experience!

The demo project demonstrating the main features you can find here. Keep in mind assemblies from the 11.2 Release (can be trial) are required.