2

WPF と MVVM は体と魂のようなものです。ViewModelそして、それが接続する可能性のある を無視することは理にかなっていますView(逆もまた同様です)。

しかし、ビューのリソース ディクショナリの参照を a 内に保持するのは罪でさえあります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>

MainWindow.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 に答える