2

WPF 和 MVVM 就像身体和灵魂。ViewModel忘记它可能连接到的东西是有道理的View(反之亦然)。

但是,将 View 的资源字典的引用保存在ViewModel. 这是否违背了目的?

例如,如果 VM 可以通过资源字典保存视图引用,则下面的代码用于 POC 目的。ViewModel可以动态更改此资源字典(基于某些输入参数)。

MyViewModel.cs

   public interface IViewInjectingViewModel
   {
      void Initialize();
      URI ViewResourceDictionary { get; }
   }

   public class MyViewModel : IViewInjectingViewModel
   {
       private URI _viewResourceDictionary;
       public void Initialize()
       {
          _viewResourceDictionary = new URI("pack://application:,,,/MyApplication;component/Resources/MyApplicationViews.xaml");
        }

        public URI ViewResourceDictionary 
        {
           get
           {
              return _viewResourceDictionary;
           }
        }
   }

MyApplicationViews.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate DataType="{x:Type local:MyViewModel}">
    <StackPanel>
        <TextBlock 
        Text="Portfolios" FontFamily="Verdana" 
        FontSize="16" FontWeight="Bold" Margin="6,7,6,4"/>
        <ListBox 
        Margin="2,1" SelectionMode="Single" 
        ItemsSource="{Binding AvailableTraders}"
        SelectedItem="{Binding SelectedTrader}" DisplayMemberPath="Name">
        <!-- ... -->
        </ListBox>
    </StackPanel>
    </DataTemplate>
</ResourceDictionary>

主窗口.xaml

<Window ...>
     <ContentControl 
    DataContext="{Binding myViewModel}"
    local:MyBehaviors.InjectView="true"/>
</Window>

常见行为:

public static class MyBehaviors
{
    public static readonly DependencyProperty InjectViewProperty 
        = DependencyProperty.RegisterAttached(..);

    //attached getters and setters...

    private static void OnInjectViewPropertyChanged(..)
    {
        var host = o as ContentControl;
        if ((bool)e.NewValue)
        {
            host.DataContextChanged
                += (o1, e1)  =>
                {
                    var viewInjectingVM = host.DataContext as IViewInjectingViewModel;
                    if (viewInjectingVM != null)
                    {
                        host.Resources.MergedDictionaries.Clear();
                        host.Resources.MergedDictionaries.Add( 
                            new ResourceDictionary() {    
                                Source = viewInjectingVM.ViewResourceDictionary 
                            });

                        host.Content = viewInjectingVM;
                    }
                };
        }
    }
}
4

1 回答 1

0

好的,我会拍的。我认为这没关系。如果您认为视图模型是表示层的一部分,那么让视图模型更改视图的资源字典以响应某些操作完全符合 MVVM 范式。

本质上,您正在更改视图的表示以响应某些操作,并且视图模型具有此责任。因此,在这种情况下更新资源字典在 MVVM 模式中似乎是有效的。

于 2012-12-03T14:58:17.763 回答