我有一个毛伊岛应用程序,其中在不同视图上跨应用程序使用 4-5 个可观察集合。目前我有一个服务,它通过存储库从数据库加载并触发一个事件来更新可观察的集合,但这需要在使用此数据的每个页面上加载。
待办服务:
public class ToDoService
{
private readonly IUnitOfWork _unitOfWork;
private readonly List<ToDo> _toDos;
public IEnumerable<ToDo> ToDos => _toDos;
public event Action ToDosLoaded;
public event Action<ToDo> ToDoAdded;
public event Action<ToDo> ToDoUpdated;
public event Action<Guid> ToDoDeleted;
public ToDoService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_toDos = new List<ToDo>();
}
public async Task Load()
{
IEnumerable<ToDo> toDos = await _unitOfWork.ToDo.GetAllAsync();
_toDos.Clear();
_toDos.AddRange(toDos);
ToDosLoaded?.Invoke();
}
public async Task Add(ToDo toDo, bool isCopy = false)
{
var saved = await _unitOfWork.ToDo.SaveAsync(toDo);
if (saved is not null)
{
_toDos.Add(toDo);
ToDoAdded?.Invoke(toDo);
}
}
public async Task Update(ToDo toDo)
{
var saved = await _unitOfWork.ToDo.SaveAsync(toDo);
if (saved is not null)
{
int currentIndex = _toDos.FindIndex(y => y.LocalId == saved.LocalId);
if (currentIndex != -1)
{
_toDos[currentIndex] = saved;
}
else
{
_toDos.Add(saved);
}
ToDoUpdated?.Invoke(saved);
}
}
public async Task Delete(ToDo toDo)
{
var deleted = await _unitOfWork.ToDO.DeleteAsync(toDo.LocalId);
if (deleted)
{
_toDos.RemoveAll(g => g.LocalId == toDo.LocalId);
ToDoDeleted?.Invoke(toDo.LocalId);
}
}
}
ToDoListingViewModel:
private readonly ToDoService _toDoStoreService;
[ObservableProperty]
private ObservableCollection<ToDoListingPreviewItemViewModel> _toDoListingPreviewItemViewModels;
public ToDoListingViewModel(ToDoService toDoStoreService)
{
ToDoListingPreviewItemViewModels = [];
_toDoStoreService = toDoStoreService;
_toDoStoreService.ToDosLoaded += ToDoStoreService_ToDosLoaded;
_toDoStoreService.ToDoAdded += ToDoStoreService_ToDoAdded;
_toDoStoreService.ToDoUpdated += ToDoStoreService_ToDoUpdated;
_toDoStoreService.ToDoDeleted += ToDoStoreService_ToDoDeleted;
ToDoListingPreviewItemViewModels.CollectionChanged += ToDoListingItemViewModels_CollectionChanged;
}
private void ToDoStoreService_ToDosLoaded()
{
ToDoListingPreviewItemViewModels.Clear();
foreach (ToDo toDo in _toDoStoreService.ToDos)
{
AddToDo(toDo);
}
}
private void ToDoStoreService_ToDoAdded(ToDo toDo)
{
AddToDo(toDo);
}
private void ToDoStoreService_ToDoUpdated(ToDo toDo)
{
ToDoListingPreviewItemViewModel toDoListingPreviewItemViewModel =
ToDoListingPreviewItemViewModels.FirstOrDefault(t => t.ToDo.LocalId == toDo.LocalId);
if (toDoListingPreviewItemViewModel != null)
{
toDoListingPreviewItemViewModel.Update(toDo);
}
}
private void ToDoStoreService_ToDoDeleted(Guid id)
{
ToDoListingPreviewItemViewModel toDoListingPreviewItemViewModel = ToDoListingPreviewItemViewModels.FirstOrDefault(y => y.ToDo?.LocalId == id);
if (toDoListingPreviewItemViewModel != null)
{
ToDoListingPreviewItemViewModels.Remove(toDoListingPreviewItemViewModel);
}
}
private void ToDoListingItemViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(Name));
}
private void AddToDo(ToDo toDo)
{
ToDoListingPreviewItemViewModel toDoListingPreviewItemViewModel = new(toDo);
ToDoListingPreviewItemViewModels.Add(toDoListingPreviewItemViewModel);
}
public void Dispose()
{
_toDoStoreService.ToDosLoaded -= ToDoStoreService_ToDosLoaded;
_toDoStoreService.ToDoAdded -= ToDoStoreService_ToDoAdded;
_toDoStoreService.ToDoUpdated -= ToDoStoreService_ToDoUpdated;
_toDoStoreService.ToDoDeleted -= ToDoStoreService_ToDoDeleted;
ToDoListingPreviewItemViewModels.CollectionChanged -= ToDoListingItemViewModels_CollectionChanged;
}
通过这种方式我可以简单地创建
public ToDosListingViewModel ToDos { get; }
ToDos = new ToDosListingViewModel (_todosStoreService);
// and load data
await _todosStoreService.Load();
通过此设置,如果任何页面需要使用此集合,我需要首先加载所有内容,如果发生任何更改,它将触发之前已加载的所有列表,以更新整个应用程序中的所有列表。这很棒,但我想避免多次加载并订阅要更新的事件。如何在整个应用程序中使用一个列表属性?
我是否应该将 ToDosListingViewModel 和 ToDoService 单例化,当应用程序启动时,我只需加载所有数据一次,仅此而已? 我应该在 App.cs 中添加一个全局列表变量吗?
为此,您可以为您的应用程序创建一个静态全局类。您可以在您的应用程序中访问和更新这些参数。
例如,我们可以先定义一个全局类(AppData.cs)并添加一个变量
Items_test
:
public static class AppData
{
public static ObservableCollection<string> Items_test { get; set; } = new ObservableCollection<string>() {"test1", "test2" };
}
然后我们可以在应用程序的任何页面上访问
ObservableCollection<>
类型的变量。
例如:
AppData.Items_test.Add("test3");