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