(我正在使用GalaSoft.MvvmLight
框架)
我的MainWindow.xaml
中有一些观点,我通过用户选择在运行时动态切换它们。
这些视图使用以下技术与相应的视图模型绑定:
MainWindow.xaml
...
<Window.Resources>
<DataTemplate DataType="{x:Type vm:Control1ViewModel}">
<v:Control1/>
</DataTemplate>
... // Assume there is more then one DataTemplate. Every view has a unique view-model.
</Window.Resources>
...
Control1ViewModel.cs
public class Control1ViewModel : ViewModelBase
{
...
}
MainWindow.xaml
使用以下技术在上述视图之间切换:
MainWindow.xaml
...
<ContentControl Content="{Binding CurrentView}"/> // This is were the view appears.
...
MainViewModel.cs
public class MainViewModel : ViewModelBase
{
...
private ViewModelBase _currentView;
public ViewModelBase CurrentView
{
get { return _currentView; }
private set
{
_currentView = value;
base.RaisePropertyChanged("CurrentView");
}
}
...
}
为方便起见,我没有添加更多控件,只需添加一个(Control1
)来缩短问题代码部分。如上所述,假设有多个视图可以切换。
每次 CurrentView
属性设置为新的ViewModelBase
值(例如Control1ViewModel
), WPF将构建绑定视图的新实例DataTemplate
可视树对象,因此旧的对象将丢失。
这意味着我无法在切换视图时缓存视图(例如Control1
)。
我在答案中找到的唯一解决方案是&#34;硬编码&#34; View及其ViewModel(使用DataContext),但遵循此解决方案会发生以下情况:
CurrentView
签名并将其移至我MainWindow.xaml
后面的代码。ViewModelBase
类型,而是切换具体的控件。我想知道是否有任何解决方案没有&#34;硬编码&#34;视图模型的视图,所以我可以保持当前的ViewModelBase
开关和ViewModel-First方法。
答案 0 :(得分:5)
您可以采用以下方法:
ContentControl
采取ItemsControl
<ItemsControl ItemsSource="{Binding Views}" SelectedItem="{Binding CurrentView}"/>
将ItemsPanel
ItemsControl
作为网格,SelectedItem
将Z-Index
设置为1,其余项目Z-Index
设为MainViewModel
0.通过这种方式,一次只能看到一个视图,而这个视图将会超过其他视图。
在Views
中选择两个属性。 ObservableCollection<ViewModelBase>
类型的CurrentView
和ViewModelBase
类型的ItemsControls
,并分别与ItemsSource
的{{1}}和SelectedItem
绑定。
现在,当您要打开视图时,创建一个ViewModel,将其添加到Views列表并将其设置为CurrentView。如果它已经在列表中,只需将其设置为CurrentView。
如果您希望永久关闭按钮,也可以提供关闭按钮。即如果您将其关闭,它将从列表中删除,不会被缓存。
这就好像您在窗口中打开了不同的视图,并且可以在它们之间切换。如果你想要,你可以关闭一个视图。
修改强> 见下面的代码:
<ItemsControl ItemsSource="{Binding Views}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Margin="10,10,0,10">
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Opacity" Value="{Binding ZIndex}"/>
<Setter Property="Grid.ZIndex" Value="{Binding ZIndex}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
您可以在ViewModel
中看到,您必须拥有一个属性ZIndex
,该属性将用于显示顶部的当前视图。因此,只要您想显示视图,只需将ZIndex
的{{1}}属性设置为1,然后将重置视图重置为0.