根据ViewModel属性更改画笔

时间:2015-10-09 15:48:01

标签: c# wpf mvvm mvvm-light fody-propertychanged

我的应用程序有CarViewModel + viewUserControl)。 我想要实现的是在绑定的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();
    }
}

默认情况下,应用程序和everthing有一个分散在多个文件上的黑暗主题。这个MyBrushes.Light会覆盖其中一些。

但我不知道如何以MVVM友好的方式基于ViewModel中的属性更改来执行LoadThemeResources函数。

我可以在视图后面的代码中执行:

var vm = (CarViewModel) DataContext;
vm.Car.PropertyChanged += HandleStatusChanged;

但这是ViewViewModel之间的紧密耦合。

我也可以通过Messenger(来自MVVM Light)来实现,但是在整个应用程序中广播并且看起来有点过分。

还有其他方法吗?或者首选方式?

2 个答案:

答案 0 :(得分:1)

您可以绑定到ViewModel上的属性,并在View中使用IValueConverter将该属性(无论是布尔值,状态枚举等)转换为要使用的Brush。

也就是说,加载转换器中的主题/资源(View和ViewModel之间的故意桥接),以便您的View获得它想要的Brush,并且您的ViewModel只需要公开“重要”信息(有助于决定的位)什么刷加载)。决策逻辑全部在转换器中。

答案 1 :(得分:1)

我会准备一些附加属性(在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的类声明一个正常的DependencyProperty,并使用它而不是附加的属性(用法是相同的)。