【问题标题】:Sharing context between view models在视图模型之间共享上下文
【发布时间】:2011-01-08 19:28:25
【问题描述】:
我正在构建我的第一个 Silverlight 应用程序。这个应用程序有几种表单,允许用户保存客户、供应商、员工等。每个页面都有一个父用户控件(具有相应的视图模型)和一个或多个子用户控件(每个都有自己的视图模型)。例如,客户表单将客户用户控件作为父用户控件,将地址用户控件、电话号码用户控件作为表单上的子用户控件。现在,父“客户”负责确保在用户单击“保存”按钮时为客户、地址和电话保存数据。在幕后,我可以在客户、地址和电话号码视图模型之间共享一个数据上下文实例。因此,当单击 Save 按钮时,客户用户控件可以保存所有三个的数据(因为它的 datacontext 也将具有 Address 和 PhoneNumber 实体)。
我想知道如何将此数据上下文从客户传递到地址和电话号码?一种方法是在各自的构造函数中将数据上下文传递给地址和电话号码视图模型,但是我需要确保仅在创建客户视图模型后才调用地址和电话号码构造函数。有没有更好的解决方案? MEF 有没有更好的解决方案?
【问题讨论】:
标签:
silverlight
viewmodel
mef
datacontext
【解决方案1】:
您拥有 Silverlight 客户端的强大功能。意思是:你有静态 :-)
我在最近的应用程序中这样做的方式是创建一个 ContextCache。基本上,它是一个静态类,它包含我的所有 RIA 上下文,以便在我的任何 ViewModel 中使用。像这样:
public static class ContextCache
{
private static TicketContext _ticketContext;
public static TicketContext TicketContext
{
get
{
if (_ticketContext == null)
_ticketContext = new TicketContext();
return _ticketContext;
}
private set { _ticketContext = value; }
}
}
因此,在 ViewModel 中,您只需调用 ContextCache.TicketContext 即可保存更改。通过这种方式,您可以利用 RIA 中的所有状态更改跟踪,并让它为您处理有关对象持久性的所有细节(如果您正确编码了服务,那是另一回事了)。
【解决方案2】:
也许对于您的架构,一个糟糕的解决方案可能是使用IsolatedStorageFile,您可以模拟 ASP.NET 的会话!
据我了解,您正试图在您的应用程序中过度使用 MV-VM 模式! ViewModel 出现在我们生活中的重要原因之一是因为可单元测试!如果我是你,我会有一个 Customer ViewModel 并在我所有的 child-usercontrols 中使用它!
如果子控件需要单独的ViewModel,则根据复杂性和隔离性,您可以考虑使用父级ViewModel 并具有子级ViewModel 的属性。
public class ParentViewModel : FrameworkElement {
Child1ViewModel Child1 { get; set; } //Must be a dependency property
Child1ViewModel Child2 { get; set; } //Must be a dependency property
ICommand SaveButtonCommand; //Your delegate command of your save button
public ParentViewModel() {
Child1 = new Child1ViewModel();
Child2 = new Child2ViewModel();
}
}
您可以在您的 Parent XAML 上使用此父视图
<UserControl.DataContext>
<ViewModels:ParentViewModels />
</UserControl.DataContext>
<Controls:Child1 DataContext="{Binding Child1}" />
<Controls:Child2 DataContext="{Binding Child2}" />
您的ParentViewModel 中也有ICommand SaveButtonCommand,并在您的孩子ViewModel 中使用properties 进行操作!
希望对你有所帮助!