Wpf – Setting WPF Window Background to Resource Dictionary Brush User Setting

application-settingswpfxaml

I have two brushes declared in my ResourceDictionary and I would like the user to select which background they want to see on the main window.

Resource Dictionary Brushes:
x:Key="LightBlueMainWindow"
x:Key="DarkBlueMainWindow"

Window:
Background="{DynamicResource LightBlueMainWindow}">

I have a project User Setting defined 'MainBackground' which is a string and can contain either key (LightBlueMainWindow or DarkBlueMainWindow).

What is the best way to dynamically set the background based on the user setting in XAML?

EDIT

I need to mention that I need to access this brush from many different user controls and windows throughout the application. I don't want to set a property on every single place I want to set this brush.

Also, the brushes are pre-defined and not just a color like this

<LinearGradientBrush x:Key="LightBlueMainWindow" EndPoint="0.5,1" 
                     MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
    <LinearGradientBrush.GradientStops>            
        <GradientStopCollection>
            <GradientStop Color="#FFE9EFF3" />
            <GradientStop Color="#FF84A1B8" Offset="1"/>
        </GradientStopCollection>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

Best Answer

It will require a couple of steps

You'll need a converter since you can't bind x:Key of a StaticResource or DynamicResource. For the converter to be able to get easy access to the resources they should be added at appliaction level

<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="BrushesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <local:ApplicationResourceKeyConverter x:Key="ApplicationResourceKeyConverter"/>
        </ResourceDictionary>
    </Application.Resources>
</Application>

ApplicationResourceKeyConverter

public class ApplicationResourceKeyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string key = value as string;
        return Application.Current.TryFindResource(key);
    }

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

Then you can bind the MainWindow Background property to the user settings string MainBackground like

<Window ...
        xmlns:ProjectProperties="clr-namespace:YourProjectName.Properties" 
        Background="{Binding Source={x:Static ProjectProperties:Settings.Default},
                             Path=MainBackground,
                             Converter={StaticResource ApplicationResourceKeyConverter}}">
    <!--...-->
</Window>
Related Topic