我有一个场景,其中至少有两个屏幕将同时显示,具有相同的来源。在一个屏幕上,此数据是只读的,另一个是可编辑的。我需要在两个屏幕上同步数据。此外,数据可以由不同的用户修改。
让我们说这是一系列行动:
可能存在超过2个屏幕包含来自同一来源(集合类型)的数据的情况。
我使用MVVM light和ViewModelLocator模式将ViewModel暴露给Views。目前我在ViewModel的构造函数中获取数据。这意味着如果我将ViewMOdel实例缓存以供重用,我将只获取一次数据,所有屏幕将使用相同的集合作为源,因此同步自动完成。这也意味着,如果网络上的其他用户更改数据,则新数据将永远不可见,因为数据仅被提取一次(在创建ViewModel期间)。
另一种方法是ViewModelLocator每次请求时都返回ViewModel的新实例。这意味着始终会获取来自数据库的新数据,因此不再存在更改数据的其他网络用户的问题。但是,在这种情况下,每个ViewModel将包含不同的集合数据实例,因此只会自动同步数据编辑,不会自动添加/删除实体。
那么,在请求ViewModel时获取新数据的最佳方法是什么,并且还在不同屏幕之间同步数据?
答案 0 :(得分:1)
由于您使用的是MVVM Light的ViewModelLocator,因此您可能会使用类似
的代码public class ViewModelLocator
{
static ViewModelLocator()
{
// register your types with your favourite DI container
}
public MainViewModel Main
{
get
{
var vm = // resolve singleton instance, data obtained in constructor
return vm;
}
}
这样的简单更改是否足以满足您的要求?
public class ViewModelLocator
{
...
public MainViewModel Main
{
get
{
var vm = // resolve singleton instance
vm.RefreshData(); // data obtained/updated here
return vm;
}
}
答案 1 :(得分:1)
我在评论中解释了这一点,所以我创建了example我正在谈论的内容。它使用的是CM,但这个想法可以转移到MVVM-light。
我创建了2个视图模型:SharingScreen1ViewModel
和SharingScreen2ViewModel
以及2个视图:SharingScreen1View
和SharingScreen2View
。
每个VM都会注入SharedViewModel单例。从左侧导航,您可以在2个视图之间切换。 SharedDataViewModel
属性最初是在SharingScreen1ViewModel
中的OnInitialize方法中设置的。然后单击按钮可以在SharingScreen2ViewModel中更改值。切换回View one,并且值也已更改。
当我提到DispatcherTimer时,我指的是每30秒刷新一点数据的要求。计时器是更新此数据的众多方法之一。正如您在本示例中所看到的,当初始化第一个ViewModel时,数据被设置一次,当用户单击按钮时,数据将在另一个ViewModel中再次设置。
接口SharedViewModel
实现:
public interface ISharedViewModel
{
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
}
SharingScreen1ViewModel:
[Export(typeof (SharingScreen1ViewModel))]
public class SharingScreen1ViewModel : Screen
{
[ImportingConstructor]
public SharingScreen1ViewModel(ISharedViewModel sharedViewModel)
{
DisplayName = "Shared Data Screen 1";
SharedViewModel = sharedViewModel;
}
public ISharedViewModel SharedViewModel { get; set; }
protected override void OnInitialize()
{
base.OnInitialize();
SharedViewModel.FirstName = "Jimmy";
SharedViewModel.LastName = "Hugh";
SharedViewModel.Address = "555 South St.";
}
}
SharingScreen2ViewModel:
[Export(typeof (SharingScreen2ViewModel))]
public class SharingScreen2ViewModel : Screen
{
[ImportingConstructor]
public SharingScreen2ViewModel(ISharedViewModel sharedViewModel)
{
DisplayName = "Shared Data Screen 2";
SharedViewModel = sharedViewModel;
}
public ISharedViewModel SharedViewModel { get; set; }
public void ChangeSharedData()
{
SharedViewModel.FirstName = "New First Name";
SharedViewModel.LastName = "New Last Name:";
SharedViewModel.Address = "New Address";
}
}