(我正在使用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>
...
Run Code Online (Sandbox Code Playgroud)
Control1ViewModel.cs
public class Control1ViewModel : ViewModelBase
{
...
}
Run Code Online (Sandbox Code Playgroud)
将MainWindow.xaml使用以下技术上述视图之间切换:
MainWindow.xaml
...
<ContentControl Content="{Binding CurrentView}"/> // This is were the view appears.
...
Run Code Online (Sandbox Code Playgroud)
MainViewModel.cs
public class MainViewModel : ViewModelBase
{
...
private ViewModelBase _currentView;
public ViewModelBase CurrentView
{
get { return _currentView; }
private set
{
_currentView = value;
base.RaisePropertyChanged("CurrentView");
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
为方便起见,我没有添加更多控件,只需添加一个(Control1)来缩短问题代码部分.如上所述,假设有多个视图可以切换.
每次在CurrentView一个新的设置属性ViewModelBase值(例如Control1ViewModel),WPF将构建绑定的视图的一个新实例DataTemplate视觉树对象,所以旧将会丢失.
这意味着我无法Control1在它们之间切换时缓存视图(例如).
我在回答中找到的唯一解决方案是使用ViewModel(使用DataContext)对视图进行"硬编码",但遵循此解决方案会发生以下情况:
CurrentView签名并将其移动到我后面的代码中MainWindow.xaml.ViewModelBase我没有切换类型,而是切换具体的控件.我想知道是否有任何解决方案没有用视图模型"硬编码"视图,所以我可以保持当前的ViewModelBase开关和ViewModel-First方法.
您可以采用以下方法:
ContentControl采取一个ItemsControl<ItemsControl ItemsSource="{Binding Views}" SelectedItem="{Binding CurrentView}"/>
拿ItemsPanel的ItemsControl是一个网格和SelectedItem设置Z-Index为1和设置项目的其余部分Z-Index为0.这样只有一个视图会在同一时间,这将是比其他的看法是可见的.
拿两个属性MainViewModel.Views类型ObservableCollection<ViewModelBase>和CurrentView类型ViewModelBase,并分别与ItemsControls's ItemsSource和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>
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到,您ViewModel必须拥有一个属性ZIndex,该属性将用于显示顶部的当前视图.因此,只要您想显示视图,只需将ZIndexproperty属性设置ViewModel为1并将重置视图重置为0即可.
| 归档时间: |
|
| 查看次数: |
982 次 |
| 最近记录: |