如何使不同屏幕上显示的同一来源的数据保持同步
本文关键字:数据 同步 屏幕 显示 何使不 | 更新日期: 2023-09-27 18:29:38
我有一个场景,其中至少有两个屏幕将同时显示,它们具有相同的源。在一个屏幕上,该数据是只读的,在另一个屏幕是可编辑的。我需要同步两个屏幕上的数据。此外,不同的用户可以修改数据。
假设这是一系列行动:
- 用户打开一个包含集合a中只读数据的屏幕a
- 用户需要向集合A添加新项目,因此屏幕B打开
- 用户在屏幕B上添加了3个新项目,然后将其关闭
- 屏幕上的集合A需要包含新项目
可能存在两个以上屏幕包含来自同一来源(收集类型)的数据的情况。
我使用MVVM灯光和ViewModelLocator模式来向视图公开ViewModels。目前我在ViewModel的构造函数中获取数据。这意味着,如果我缓存ViewMOdel实例以供重用,我将只获取一次数据,所有屏幕都将使用相同的集合作为源,因此同步是自动完成的。这也意味着,如果网络上的其他用户更改数据,新数据将永远不可见,因为数据只提取一次(在ViewModel创建期间)。
另一种方法是,ViewModelLocator每次被请求时都会返回ViewModel的新实例。这意味着总是从数据库中提取新的数据,所以其他网络用户更改数据的问题不再存在。但是,在这种情况下,每个ViewModel将包含不同的集合数据实例,因此只有数据的编辑会自动同步,添加/删除实体不会自动同步。
那么,在请求ViewModel时获取新数据,并在不同屏幕之间同步数据的最佳方式是什么?
我在评论中解释得很差,所以我创建了一个我所说的例子。它使用CM,但这个想法可以转移到MVVM光。
我创建了两个视图模型:SharingScreen1ViewModel
和SharingScreen2ViewModel
,以及两个视图: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";
}
}
由于您使用的是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;
}
}