我有一个类似WPF UI的Outlook,左侧是导航,顶部是工具栏,底部是状态栏,都在DockPanel
内。
应用程序的“主要”区域在DataGrid
范围内是LastChild,因此填充剩余空间,目前看起来像这样:
<Grid DockPanel.Dock="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<views:View1 Grid.Column="0" Grid.Row="0"/>
<views:View2 Grid.Column="0" Grid.Row="0"/>
<views:View3 Grid.Column="0" Grid.Row="0"/>
<views:View4 Grid.Column="0" Grid.Row="0"/>
</Grid>
这些视图都是具有自己的ViewModel的用户控件,其Visibility
属性绑定到其ViewModel中的属性,并由导航窗格选择控制。选择导航窗格项时,主ViewModel会向视图的ViewModel发送消息,并在收到消息后,视图的ViewModels会相应地设置其Visibility
属性...
现在,这种方法很好但感觉不对,因为这些视图的所有ViewModel都是在app start上实例化的,而不是在选择相关的导航窗格时提出有关性能和内存使用的问题......
我的问题是,当选择相关的导航窗格时,是否有一种方法可以“按需”加载每个视图及其ViewModel,当选择不同的导航窗格而不使用PRISM / MEF时,可以卸载这些视图和ViewModel一些其他的插件架构...而且,更一般的是如何在主视图中构建一个具有多个视图/ ViewModel“嵌入”的应用程序?
答案 0 :(得分:8)
这就是我的所作所为:
首先,在您的主ViewModel(为主窗口提供服务的ViewModel)上添加一个Content属性:
object _content;
public object Content
{
get { return _content; }
set
{
_content = value;
RaisePropertyChanged("Content");
}
}
当用户从视图切换到视图时,将Content
属性设置为他们选择的视图的相应ViewModel。
然后,在主窗口中,您可以使用ContentControl显示当前的Content ViewModel:
<ContentControl Content="{Binding Content}" />
...以及上面某处,为Content
可能设置为的各种ViewModel定义一个DataTemplate:
<DataTemplate DataType="{x:Type vm:FooViewModel}">
<my:FooUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:BarViewModel}">
<my:BarUserControl />
</DataTemplate>
现在,ContentControl将负责初始化和显示每个UserControl,具体取决于哪个ViewModel当前处于“活动状态”。