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;
}
};
}
}
}