views:

41

answers:

2

I really like WPF because of its awesome skinning support by changing resourcedictionaries on the fly, but the catch is, the styles must be made by designers in XAML. My client needs a skinnable UI where the end users can make skins themselves. My question is -

In Photoshop, you can take any image, and add a color overlay to change all the colors to that hue. Can you do something similar in WPF? I'm just a beginner, and looking at several WPF styles, it seems like all the color values are hard-coded.

Here's a sample scenario - user selects two colors from color pickers, and all the controls have a gradient background from Color1 to Color2.

EDIT: Can the colors be saved to a XML file and loaded again too?

A: 

You could store the color values in XML/DataBase (sqllite might be a good fit) and put them into a class that the controls will bind to. That way you can use a colorpicker for the user to change these data.

Goblin
+1  A: 

The key is to realize that a Style can contain a DynamicResource or a Binding, so if your style is:

<Style TargetType="{x:Type Button}">
  <Setter Property="Background" Value="{DynamicResource UserSelectedBackground}" />
  ...
</Style>

anything you set as a "UserSelectedBackground" resource will be applied to all buttons.

Alternatively you might bind to a view model object:

<Style TargetType="{x:Type Button}">
  <Setter Property="Background" Value="{Binding ButtonBackground, Source={x:Static my:SkinModel.Instance}" />
  ...
</Style>

Now whenever ButtonBackground in your SkinModel instance changes, all button backgrounds will automatically update. (This assumes your SkinModel uses DependencyProperties or implements INotifyPropertyChanged.)

To allow the user to separately control the two ends of a gradient fill, create two SolidColorBrush properties in your SkinModel which are bound from two-way by the color pickers. Whenever these properties change, recompute the ButtonBackground property (either in the PropertyChangedCallback of a DependencyProperty or in the setter of a CLR property).

Saving your state to the file is trivial: Just use XamlWriter to serialize your SkinModel to XAML, then write it to the file. To load it later, just use XamlReader.Parse.

Ray Burns