这取决于。第一个问题是您将创建什么样的 ViewModel 类。我认为为每个页面创建一个 ViewModel 类是一个很好的约定,例如为 MainPage 创建一个名为 MainPageViewModel 的类。
这个MainPageViewModel 应该负责从数据库加载数据,最好是在它的构造函数中。由于您必须使用项目计数来扩展您的组,因此您也可以为您的组创建一个 ViewModel 类,称为 GroupViewModel,而 MainPageViewModel 将有一个名为 Groups 的属性,类型为 ObservableCollection<GroupViewModel>。
另一个有趣的问题是在哪里实例化MainPageViewModel?我看到了三种不同的方法:
1 直接在 XAML 中创建 ViewModel
您可以在您的页面中创建 ViewModel 实例并将其直接用作DataContext,如下所示:
<Page xmlns:local="using:MyApp">
<Page.DataContext>
<local:MainPageViewModel />
</Page.DataContext>
...
</Page>
我认为这可能是最糟糕的解决方案,因为它需要 ViewModel 有一个无参数构造函数(这种情况很少发生),而且它非常不灵活 ,您无法控制何时创建 ViewModel 实例。
2 在后面的代码中实例化 ViewModel
您可以像这样在代码中简单地创建 ViewModel 实例:
this.DataContext = new MainPageViewModel();
您可以在构造函数中执行此操作 - 这样将为每个 Page-instance 创建一个 ViewModel-instance - 或在 OnNavigatedTo 事件处理程序中 - 这样每次用户导航到时都会创建一个新 ViewModel-instance你的页面。
这种方法更灵活一些,但是将代码放在页面后面的代码中,这在纯 MVVM 中应该避免。不过,这个解决方案可能是最简单的。
3 ViewModelLocator 模式
最后一个解决方案最复杂,需要的代码最多,但在我看来也是最好的。
您将需要一个类,其唯一目的是创建 ViewModel 实例,称为 ViewModelLocator,它为每个页面的 ViewModel 定义属性:
class ViewModelLocator
{
MainPageViewModel MainPageViewModel
{
get
{
return new MainPageViewModel();
}
}
}
定位器的一个实例必须在 App.xaml 中创建为静态资源:
<Application.Resources>
<ResourceDictionary>
...
<local:ViewModelLocator x:Key="ViewModelLocator" />
</ResourceDictionary>
</Application.Resources>
然后你可以简单地将这个实例的属性绑定到你页面上的DataContext:
<Page DataContext="{Binding MainPageViewModel, Source={StaticResource ViewModelLocator}}">
...
</Page>
这样每次创建页面时,都会调用 ViewModelLocator 类的 MainPageViewModel 属性。在上面的示例中,我以一种每次都创建一个新实例的方式实现了该属性,但是修改它以便为每个实例重用一个实例很容易场合。
通过这种模式,ViewModel 实例的创建和管理与页面逻辑完全解耦,这种方案是最灵活和可扩展的(例如实现设计时数据真的很简单和它)。