Как синхронизировать данные из одного источника на разных экранах - PullRequest
0 голосов
/ 31 марта 2012

У меня есть сценарий, в котором одновременно будут отображаться как минимум 2 экрана с одинаковым источником.На одном экране эти данные доступны только для чтения, на другом редактируются.Мне нужны данные на обоих экранах для синхронизации.Кроме того, данные могут быть изменены разными пользователями.

Допустим, что это последовательность действий:

  1. пользователь открывает экран A, который содержит данные только для чтения из коллекции A
  2. Пользователь должен добавить новые элементы в collectionA, поэтому screenB открывает
  3. пользователь добавляет 3 новых элемента на screenB, а затем закрывает их
  4. collection на screenA должен иметь новые элементы

Могут быть случаи, когда более 2 экранов содержат данные из одного и того же источника (тип сбора).

Я использую MVVM light и шаблон ViewModelLocator для представления ViewModels для Views.В настоящее время я выбираю данные в конструкторе ViewModel.Это означает, что если я кеширую экземпляр ViewMOdel для повторного использования, я получу данные только один раз, все экраны будут использовать одну и ту же коллекцию как источник, поэтому синхронизация выполняется автоматически.Это также означает, что если другой пользователь в сети изменяет данные, новые данные никогда не будут видны, поскольку данные выбираются только один раз (во время создания ViewModel).

Другой подход заключается в том, что ViewModelLocator каждый раз возвращает новый экземпляр ViewModelэто запрашивается.Это означает, что свежие данные из базы данных всегда выбираются, поэтому проблема с другими пользователями сети, меняющими данные, больше не существует.Однако в этом случае каждая ViewModel будет содержать разные экземпляры данных сбора, поэтому только синхронизация редактирования данных выполняется автоматически, добавление / удаление объекта не синхронизируется автоматически.

Итак, каков наилучший способсвежие данные получены при запросе ViewModel, а также синхронизированы данные между различными экранами?

Ответы [ 2 ]

1 голос
/ 01 апреля 2012

Я плохо объяснил это в своих комментариях, поэтому создал пример того, о чем я говорил. Он использует CM, но идею можно перенести в MVVM-light.

Я создал 2 модели вида: SharingScreen1ViewModel и SharingScreen2ViewModel и 2 вида: SharingScreen1View и SharingScreen2View.

Каждая виртуальная машина получает синглтон SharedViewModel. С левой навигационной панели вы можете переключаться между двумя видами. Свойства SharedDataViewModel изначально устанавливаются в методе OnInitialize, который находится в SharingScreen1ViewModel. Затем значения можно изменить в 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";
        }
    }
1 голос
/ 01 апреля 2012

Поскольку вы используете ViewModelLocator MVVM Light, у вас предположительно есть код, похожий на

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;
        }
    }
...