2

我有一个带有CarViewModel+ view( UserControl) 的应用程序。我想要实现的是在绑定的DataContextCar.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)来做到这一点,但这会在整个应用程序中进行广播,而且似乎有点过分了。

还有其他方法吗?还是首选方式?

4

2 回答 2

1

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

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

于 2015-10-09T15:51:02.847 回答
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>

您还可DependencyProperty以为您的 UserControl 的类声明一个法线并使用它而不是附加属性(用法相同)。

于 2015-10-09T21:50:24.110 回答