问题
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>
回答1:
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>
回答2:
Instead of using DynamicResource, just have the user pick and set the background, or have a property called UserChosenColor and bind the Background to that.
You could also bind to the property in your settings (MainBackground) by using a converter that converted a string to a Brush.
Edit
Since the user changed his question as a method of setting every window to a chosen background, it's also simple. Define a style with a setter like this:
<!-- Window style -->
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="{Binding MainBackground, Mode=OneWay, Converter=StringToBrushConverter}"/>
</Style>
来源:https://stackoverflow.com/questions/6710265/setting-wpf-window-background-to-resource-dictionary-brush-user-setting