我有一个带有菜单和内容控件的窗口。当我加载一个模块时,它会检查该模块是否已经打开,如果尚未创建,则将其添加到模块集合中并使其成为当前活动模块。他们是这样设置的
MainWindowViewModel.cs
private void ChangeViewModel(Object parameter)
{
string name = (string) parameter;
IPageViewModel page;
if (PageViewModels.FirstOrDefault(vm => vm.Name == name) != null)
{
CurrentPageViewModel = PageViewModels
.FirstOrDefault(vm => vm.Name == name);
}
else
{
if (name == "TimeSheets")
{
page = new TimeSheetViewModel();
}
else if (name == "Test")
{
page = new TestViewModel();
}
else
{
page = new HomeViewModel();
}
CurrentPageViewModel = page;
PageViewModels.Add(page);
}
}
MainWindow.xaml
<Window.Resources>
<DataTemplate DataType="{x:Type local:HomeViewModel}">
<local:Home />
</DataTemplate>
<DataTemplate DataType="{x:Type local:TimeSheetViewModel}">
<local:Timesheet />
</DataTemplate>
<DataTemplate DataType="{x:Type local:TestViewModel}">
<local:Test />
</DataTemplate>
</Window.Resources>
<Grid x:Name="gridContent" Margin="70,42,20,20" >
<ContentControl Content="{Binding CurrentPageViewModel}" />
</Grid>
这似乎可以在模块/页面之间进行切换,但是在一个页面上,我有一个具有自己的datacontext的用户控件,每次离开该页面时都会收集垃圾并在返回该页面时重新实例化
TimeSheet.xaml
<Grid>
<local:EmployeeList />
</Grid>
EmployeeList.xaml
<UserControl.DataContext>
<local:EmployeeListViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.Background>
<SolidColorBrush Color="{StaticResource LIGHT_Main}"/>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Search "/>
<TextBox Grid.Column="1" Text="{Binding SearchParameter, UpdateSourceTrigger=PropertyChanged}" Margin="4,0,4,0"/>
<Image Grid.Column="2" Source="pack://application:,,,/Images/Icons/SearchTiny.png" Margin="5,0,8,0"/>
</Grid>
<Grid Grid.Row="1" Margin="6">
<DataGrid x:Name="gridEmployees" ItemsSource="{Binding EmployeesFiltered}" MaxHeight="500" VerticalAlignment="Stretch" AutoGenerateColumns="False" CanUserReorderColumns="False" CanUserSortColumns="False" HorizontalGridLinesBrush="{StaticResource GridLines}" VerticalGridLinesBrush="{StaticResource GridLines}" SelectionMode="Single" IsReadOnly="True" Width="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" Width="200"/>
<DataGridTextColumn Header="Badge" Binding="{Binding Badge}" IsReadOnly="True" Width="1*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Grid>
因此,当加载完毕时,我可以搜索工作正常的员工列表,但是,一旦加载了其他模块,垃圾收集器就会删除我的搜索参数和员工列表,因此必须重新加载它们。如果我使EmployeeList.xaml的数据上下文与TimeSheet.xaml的相同,并添加必填字段,则在模块之间切换时我不会丢失搜索参数,但是EmployeeList是一个控件,我想在程序的多个位置使用它拥有自己的数据上下文会很好。
让我知道这是否没有道理,或者我的方法是错误的。
谢谢!
答案 0 :(得分:0)
我不认为所有控件都必须具有自己的VM。我通常用代码编写页面具有VM,并将这些值传递给控件上的各个依赖项属性。
如果您有需要在多个控件之间共享的数据,则该数据应仅存在于一个VM上,并作为依赖属性传入。
但是...顺便说一句,我会将这些VMS作为主VM上的属性,并且每个控件datacontext都会自动继承其父级datacontext...。这时可以为每个控件获取正确的数据然后将成为绑定(路径)到原始VM上正确位置的练习。