I have an application which has CarViewModel
+ view
(UserControl
).
What I want to achieve is to change the style of brushes when the bound DataContext Car.Status
changes.
I found out how to change the brushes (in code behind of the view):
private void LoadThemeResources(bool isPrepareMode)
{
if (isPrepareMode)
{
Uri themeUri = new Uri(@"/../Resources/MyBrushes.Light.xaml", UriKind.Relative);
ResourceDictionary themeDictionary = Application.LoadComponent(themeUri) as ResourceDictionary;
this.Resources.MergedDictionaries.Add(themeDictionary);
}
else
{
this.Resources.MergedDictionaries.Clear();
}
}
By default the application and everthing has a dark theme spread over multiple files. This MyBrushes.Light
overwrites some of those.
But I have no clue how I can execute the LoadThemeResources function based on a property change in the ViewModel in a MVVM friendly way.
I can do in the code behind of the view:
var vm = (CarViewModel) DataContext;
vm.Car.PropertyChanged += HandleStatusChanged;
But this is a tight coupling between View
and ViewModel
.
I can also do it via Messenger (From MVVM Light), but that gets broadcasted throughout the whole application and seems overkill.
Is there an other way? Or preferred way?
You could bind to a property on your ViewModel, and use an IValueConverter in your View to turn that property (whether boolean, status enumeration, whatever) into a Brush to be used.
That is, load the theme/resources in the converter (a deliberate bridge between View and ViewModel) so that your View gets the Brush it wants and your ViewModel only has to expose the 'important' information (the bits that help decide what brush to load). The decision logic is all in the converter.
I would prepare some attached property (used on
UserControl
). Bind that property to your view-model and add code logic ofLoadThemeResources
in the property changed callback, something like this:Usage in XAML:
You can also declare a normal
DependencyProperty
for your UserControl's class and use that instead of the attached property (the usage is just the same).