Search code examples
c#wpfxamlresourcedictionary

Resource Conversion in XAML


I'm searching for a way to modify colors (SolidColorBrush's) in XAML. I've been using CSS / less for some time now (less@github) and like the way it allows me to just save one color as RGB and to say darken(@color1, 15%) to get the same coloring, but a bit darker.

Is there a way to apply such Converters in XAML / C#.Net? Something like (pseudo xaml):

<SolidColorBrush x:Key="darkRed" 
                 Color="{StaticResource Red, Converter=Darken}" />

Edit: sa_ddam's answer is almost what I need. But - I can't get it to work when using it in a ResourceDictionary.

sa_ddam's code works - but the following won't:

<Window.Resources>

    <cnv:DarkenColorConverter x:Key="Darken" />

    <SolidColorBrush x:Key="blue"
                     Color="Blue" />

    <SolidColorBrush x:Key="darkblue"
                     Color="{Binding Source={StaticResource blue}, Converter={StaticResource Darken}}" />

</Window.Resources>

Edit: Found my mistake - the return type of the converter must be Color, not SolidColorBrush.


Solution

  • You could create a IValueConverter to make the color darker

    Something like this should do the trick

    public class DarkenColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double percentage = 0.8; // Default 
            if (value is SolidColorBrush)
            {
                if (parameter != null)
                {
                    double.TryParse(parameter.ToString(), out percentage);
                }
                Color color = (value as SolidColorBrush).Color;
                return new SolidColorBrush(Color.FromRgb((byte)(color.R * percentage), (byte)(color.G * percentage), (byte)(color.B * percentage)));
            }
            return value;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    

    Here is an example of the usage

    <Window x:Class="WpfApplication13.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication13"
            Title="MainWindow" x:Name="UI" Width="124" Height="336"
        >
        <Window.Resources>
            <!-- Converter -->
            <local:DarkenColorConverter x:Key="Darken" />
    
            <!-- Brush to manipulate -->
            <SolidColorBrush x:Key="red" Color="{Binding Source=Red}"  />
        </Window.Resources>
    
        <StackPanel>
            <!-- Original color -->
            <Rectangle Fill="{StaticResource red}" Width="100" Height="100" />
    
             <!-- Darken with Converter -->
            <Rectangle Fill="{Binding Source={StaticResource red}, Converter={StaticResource Darken}}" Width="100" Height="100"/>
    
            <!-- Using ConverterParameter to select how dark (0.0 - 1.0) -->
            <Rectangle Fill="{Binding Source={StaticResource red}, Converter={StaticResource Darken}, ConverterParameter=0.5}" Width="100" Height="100"/>
        </StackPanel>
    </Window>
    

    Result:

    enter image description here