Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Resourse.resx in WPF application to set color

Tags:

mvvm

wpf

I´m trying to make an application that has to be able to easily change a dll file which could change colors in the application. I´m trying to use resource manager to do this but am having problems with setting color values so that the styles for views can easily accept it. We know that(in this case) the background of a button takes in SolidColorBrush, and while

Value="Black" works,
Value={x:Static res:AppResources.Btn_Background}

which gives the string Black does not (current theory being that converters make the former work but not the latter). This is all being done in wpf & mvvm. Have you guys an idea about how this could be done.

Greetings

like image 444
Andrés Ævar Grétarsson Avatar asked Dec 02 '25 18:12

Andrés Ævar Grétarsson


2 Answers

You could use a Binding:

Background="{Binding Source={x:Static res:AppResources.Btn_Background}}"

This will cause the CoerceValue to fire for the DependencyProperty controlling the background.

@Snowbear mentioned it may be a Color rather than a String, in which case you would need to provide a trivial IValueConverter.

public class ColorConverter: IValueConverter
{
    #region IValueConverter Members

    private Dictionary<Color, Brush> brushes = new Dictionary<Color, Brush>();

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        Brush brush;
        var color = (Color)value;
        if (!brushes.TryGetValue(color, out brush))
        {
            brushes[color] = brush = new SolidColorBrush(color);
            brush.Freeze();
        }

        return brush;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}
like image 60
user7116 Avatar answered Dec 05 '25 13:12

user7116


Your specific issue is that you are bypassing the default string to Brush conversion and would need to handle that manually.

As sixlettervariables states, you'd can use a Binding if your source is a string, but that is probably overkill. At a minimum, you'd want to set Mode=OneTime on the Binding.

You can also create a custom MarkupExtension that performs the conversion.

Your conversion, whether it be through a custom IValueConverter or MarkupExtension, can leverage the BrushConverter class. So things like "Black" or "#000" will work as they do when defining the color in XAML like your first example.

EDIT:

Actually a markup extension that derives from StaticExtension, makes this easier:

public class BrushStaticExtension : StaticExtension {

    private static BrushConverter converter = new BrushConverter();

    public BrushStaticExtension() { }
    public BrushStaticExtension(string member) : base (member) { }

    public override object ProvideValue(IServiceProvider serviceProvider) {
        return converter.ConvertFrom(base.ProvideValue(serviceProvider));
    }

}
like image 42
CodeNaked Avatar answered Dec 05 '25 12:12

CodeNaked



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!