我正在为数据库使用普通模型(实体)并将它们绑定到视图。这对我很有用,但现在我有一个“特殊”要求,我认为ViewModel是正确的。
目前,我有一个包含许多项目的组模型(1:n)。所有组都从数据库加载到 ObservableCollection< Group> ,以在 LongListSelector 中显示它们。要求是使用组中当前项目数向 LongListSelector 添加第二行。这并不是很难,但我认为它是ViewModel的正确位置。
我必须从组模型对象构建ViewModel,但是哪里是正确的位置。我应该在页面的 OnNavigatedTo 中为每个组模型创建ViewModel对象吗?在这种情况下,我在页面的每个导航上创建ViewModel对象集合。还有另一种方式吗?
答案 0 :(得分:1)
这取决于。第一个问题是您将创建什么样的ViewModel类。我认为为每个页面创建一个ViewModel类是一个很好的约定,例如,为MainPage
创建一个名为MainPageViewModel
的类。
此MainPageViewModel
应该负责从数据库加载数据,最好是在其构造函数中。并且因为您必须使用项目计数扩展您的组,您也可以为您的组创建一个ViewModel类,称为GroupViewModel
,MainPageViewModel
将具有名为Groups {{1}的类的属性}}
另一个有趣的问题是在哪里实例化ObservableCollection<GroupViewModel>
?我看到了三种不同的方法:
您可以在页面中创建ViewModel实例,并将其直接用作MainPageViewModel
,如下所示:
DataContext
我认为这可能是最糟糕的解决方案,因为它需要ViewModel有一个无参数构造函数(很少这种情况),而且它非常不灵活 ,您无法控制何时创建ViewModel实例。
您可以使用以下代码创建ViewModel实例:
<Page xmlns:local="using:MyApp">
<Page.DataContext>
<local:MainPageViewModel />
</Page.DataContext>
...
</Page>
您可以在构造函数中执行此操作 - 这样就可以为每个Page-instance创建一个ViewModel实例 - 或者在OnNavigatedTo事件处理程序中 - 这样每次用户导航到时都会创建一个新的ViewModel实例。你的页面。
这种方法稍微灵活一些,但是将代码放在页面后面的代码中,这在纯MVVM中应该避免。然而,这个解决方案可能是最简单的。
最后一个解决方案是最复杂的,需要最多的代码,但在我看来也是最好的
您将需要一个类,其唯一目的是创建名为this.DataContext = new MainPageViewModel();
的ViewModel实例,它定义每个页面的ViewModel的属性:
ViewModelLocator
必须在App.xaml中将定位器的实例创建为静态资源:
class ViewModelLocator
{
MainPageViewModel MainPageViewModel
{
get
{
return new MainPageViewModel();
}
}
}
然后,您只需将此实例的属性绑定到页面上的DataContext:
<Application.Resources>
<ResourceDictionary>
...
<local:ViewModelLocator x:Key="ViewModelLocator" />
</ResourceDictionary>
</Application.Resources>
这样,每次创建页面时,都会调用ViewModelLocator类的<Page DataContext="{Binding MainPageViewModel, Source={StaticResource ViewModelLocator}}">
...
</Page>
属性。在上面的示例中,我以一种每次创建新实例的方式实现了该属性,但是为了为每个重用一个实例,它很容易修改它场合。
使用此模式,ViewModel实例的创建和管理与页面逻辑完全解耦,此解决方案是最灵活和可扩展的(例如,实现设计时数据非常简单)用它)。
答案 1 :(得分:0)
有关创建ViewModel的位置的不同方法。你使用popular MVVM frameworks中的任何一个吗?在这种情况下,您应该遵循这些框架使用的指令和机制。
如果您希望自己创建一个简单的虚拟机并将其绑定,可以在不同的地方进行操作。如果您只想要一个VM的一个实例,则可以在App.cs类中创建它,将其公开为公共,以便您可以从应用程序的任何部分访问它。 如果您有多个不同的VM,并且每个VM负责一个View,则可以将每个VM的实例保留为单个页面的一部分,仅在用户导航到该页面时才在代码中创建它。您还可以在XAML资源中创建VM实例,并从不同的部分引用它们。目前还不清楚你的用例究竟是什么,但这些是常见的解决方案。