1

I am trying to make the color scheme of my application dynamic so that I can have a color value in a property(hopefully coming from the database) that determines the color scheme of my application.

I have a Resources.xaml file where I set my colors and styles for the application, which I then use throughout all my controls and windows. I would like to bind the Color of a SolidColorBrush in the resources file to a property in my ViewModel(s) so that this color can change based on the current application value. Here is what I have so far, but it isn't working so I must be missing something.

Code in the Resources.xaml file:

<SolidColorBrush x:Key="ApplicationMainBackgroundBrush" Color="{Binding Path=MainApplicationColor, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ApplicationArchitecture:ViewModelBase}, Mode=FindAncestor}, FallbackValue=CornflowerBlue}"/>  

Code in the MainWindow.xaml file:

<Grid Grid.Row="0" x:Name="gridControl" Background="{DynamicResource ApplicationMainBackgroundBrush}">

The DataContext of my MainWindow.xaml is a class called ApplicationViewModel, which inherits from ViewModelBase, which has a property "MainApplicationColor" returning the string "Teal" to change the color of that SolidColorBrush from it's FallbackValue. I'm hard coding the color for now, but this is where I would like to get my value from the database in the future. The color is currently not changing, so I'm assuming there is something wrong in my binding source as it is clearly not working like I think it should.

Thanks,

Klara

1 Answer 1

1

The problem seems to be your SolidColorBrush.Color property's Binding.

  1. There the ancestor type should be ApplicationArchitecture:MainWindow and not ApplicationArchitecture:ViewModelBase.

  2. The Path should include the DataContext in it.

Like this....

  <SolidColorBrush x:Key="ApplicationMainBackgroundBrush"
                   Color="{Binding Path=DataContext.MainApplicationColor,
                              RelativeSource={RelativeSource FindAncestor, 
                                  AncestorType={x:Type ApplicationArchitecture:MainWindow},
                                      Mode=FindAncestor},
                                          FallbackValue=CornflowerBlue}"/>

Let me know if this helps.

Sign up to request clarification or add additional context in comments.

5 Comments

I'm trying to make this as generic/flexible as possible, so that all my applications can make use of this(the Resources file is in a common library) so I don't want to set the window that I'm currently using as the AncestorType because it wouldn't be the same object in a different application or even a different window/control in the same application that uses the style. Is there anyway to set the binding to a property in my ViewModelBase, or to specify that it looks for the binding in the current ViewModel of whatever control is using this style so that it's as flexible as possible? thanks!
You do not need to remove the ancestor-level when actually binding to the MainWindow as it cannot have another ancestor of type MainWindow, in fact the default value for AncestorLevel is already 1, so removing it does nothing.
@klarat, u can replace ApplicationArchitecture:MainWindow with generic Window assuming that the ultimate parent of any of ur applications is the Window type.
@AngelWPF: That is not quite correct, you can also have browser hosted WPF applications...
thank you, that worked! I set the AncestorType to Window and then the critical thing was for the path to point to DataContext.MainApplicationColor as @AngelWPF suggested so that it picked it up from the binding's view model. thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.