WPF和MVVM就像身体和灵魂。对于ViewModel
来说,忘记它可能连接到的View
是有道理的(反之亦然)。
但是,在ViewModel
中引用视图的资源字典甚至是一种罪过吗?这是否违背了目的?
例如,如果虚拟机可以通过资源字典保存视图引用,则以下代码用于 POC 目的。 ViewModel
可以动态更改此资源字典(基于某些输入参数)。
我的视图模型.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;
}
};
}
}
}
好的,我来拍一张照片。 我认为这没关系。 如果您将视图模型视为表示层的一部分,那么让视图模型更改视图的资源字典以响应某些操作完全符合 MVVM 范例。
本质上,您正在更改视图的表示以响应某些操作,而视图模型对此负有此责任。 因此,在此上下文中更新资源字典在 MVVM 模式中似乎有效。