根据 ViewModel 更改画笔 属性
Change brushes based on ViewModel property
我有一个包含 CarViewModel
+ view
(UserControl
) 的应用程序。
我想要实现的是当绑定的 DataContext Car.Status
改变时改变画笔的样式。
我找到了如何更改画笔(在视图后面的代码中):
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();
}
}
默认情况下,应用程序和所有内容都有一个分布在多个文件中的深色主题。 MyBrushes.Light
覆盖了其中的一些。
但我不知道如何以 MVVM 友好的方式基于 ViewModel 中的 属性 更改执行 LoadThemeResources 函数。
我可以在视图后面的代码中做:
var vm = (CarViewModel) DataContext;
vm.Car.PropertyChanged += HandleStatusChanged;
但这是 View
和 ViewModel
之间的紧密耦合。
我也可以通过 Messenger(来自 MVVM Light)执行此操作,但这会在整个应用程序中广播,似乎有点过分了。
还有别的方法吗?或者首选方式?
您可以绑定到您的 ViewModel 上的 属性,并在您的视图中使用 IValueConverter 将 属性(无论是布尔值、状态枚举,还是其他)转换为要使用的 Brush。
也就是说,在转换器中加载 theme/resources(View 和 ViewModel 之间的故意桥梁),以便您的 View 获得它想要的 Brush,而您的 ViewModel 只需要公开 'important' 信息(帮助决定加载什么画笔的位)。决策逻辑都在转换器中。
我会准备一些附件属性(用于UserControl
)。将 属性 绑定到您的视图模型,并在 属性 更改的回调中添加 LoadThemeResources
的代码逻辑,如下所示:
public static class ThemeService {
public static DependencyProperty IsPrepareModeProperty =
DependencyProperty.RegisterAttached("IsPrepareMode", typeof(bool), typeof(ThemeService),
new PropertyMetadata(isPrepareModeChanged));
public static bool GetIsPrepareMode(UserControl e){
return (bool) e.GetValue(IsPrepareModeProperty);
}
public static void SetIsPrepareMode(UserControl e, bool value){
e.SetValue(IsPrepareModeProperty, value);
}
static void isPrepareModeChanged(object sender, DependencyPropertyChangedEventArgs e){
var u = sender as UserControl;
u.LoadThemeResources((bool)e.NewValue);
}
}
//you need some public method of LoadThemeResources
public void LoadThemeResources(bool isPrepareMode) {
//...
}
在XAML中的用法:
<UserControl ...
local:ThemeService.IsPrepareMode="{Binding Car.Status}">
<!-- ... -->
</UserControl>
您也可以为您的 UserControl 的 class 声明一个普通的 DependencyProperty
并使用它来代替附加的 属性(用法是一样的)。
我有一个包含 CarViewModel
+ view
(UserControl
) 的应用程序。
我想要实现的是当绑定的 DataContext Car.Status
改变时改变画笔的样式。
我找到了如何更改画笔(在视图后面的代码中):
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();
}
}
默认情况下,应用程序和所有内容都有一个分布在多个文件中的深色主题。 MyBrushes.Light
覆盖了其中的一些。
但我不知道如何以 MVVM 友好的方式基于 ViewModel 中的 属性 更改执行 LoadThemeResources 函数。
我可以在视图后面的代码中做:
var vm = (CarViewModel) DataContext;
vm.Car.PropertyChanged += HandleStatusChanged;
但这是 View
和 ViewModel
之间的紧密耦合。
我也可以通过 Messenger(来自 MVVM Light)执行此操作,但这会在整个应用程序中广播,似乎有点过分了。
还有别的方法吗?或者首选方式?
您可以绑定到您的 ViewModel 上的 属性,并在您的视图中使用 IValueConverter 将 属性(无论是布尔值、状态枚举,还是其他)转换为要使用的 Brush。
也就是说,在转换器中加载 theme/resources(View 和 ViewModel 之间的故意桥梁),以便您的 View 获得它想要的 Brush,而您的 ViewModel 只需要公开 'important' 信息(帮助决定加载什么画笔的位)。决策逻辑都在转换器中。
我会准备一些附件属性(用于UserControl
)。将 属性 绑定到您的视图模型,并在 属性 更改的回调中添加 LoadThemeResources
的代码逻辑,如下所示:
public static class ThemeService {
public static DependencyProperty IsPrepareModeProperty =
DependencyProperty.RegisterAttached("IsPrepareMode", typeof(bool), typeof(ThemeService),
new PropertyMetadata(isPrepareModeChanged));
public static bool GetIsPrepareMode(UserControl e){
return (bool) e.GetValue(IsPrepareModeProperty);
}
public static void SetIsPrepareMode(UserControl e, bool value){
e.SetValue(IsPrepareModeProperty, value);
}
static void isPrepareModeChanged(object sender, DependencyPropertyChangedEventArgs e){
var u = sender as UserControl;
u.LoadThemeResources((bool)e.NewValue);
}
}
//you need some public method of LoadThemeResources
public void LoadThemeResources(bool isPrepareMode) {
//...
}
在XAML中的用法:
<UserControl ...
local:ThemeService.IsPrepareMode="{Binding Car.Status}">
<!-- ... -->
</UserControl>
您也可以为您的 UserControl 的 class 声明一个普通的 DependencyProperty
并使用它来代替附加的 属性(用法是一样的)。