Xamarin MVVM передает данные другим ViewModel и совместно используемой ViewModel - PullRequest
0 голосов
/ 14 января 2020

У меня есть 2 вопроса.

Первый => Как я могу передать значение между двумя ViewModels?

Например, я добавляю данные и показываю их в MainPAGE, и одновременно хочу чтобы показать те же данные (Observable Collection) в ChildPAGE тоже. Внутри ChildPAGE Xaml я назначил BindingContext для ViewModel и назначил источник данных listview для этой наблюдаемой коллекции. Но я не мог заставить ее работать. Я попробовал несколько примеров, но мне не удалось это сработать. Если данные загружаются в конструктор ChildPAGE, тогда он работает, иначе не работает. Я думал, я бы улучшил производительность с использованием одной ObservableCollection, но я думаю, что механизм в MVVM другой. Итак, как я могу использовать один ObservableCollection на 2 страницах.

Second => Как я могу передавать данные между ViewModels без использования конструктора. Пример: у меня есть 2 страницы (MainPage и ChidPage) и 2 модели представления (MainVM и ChildVM).

Ситуация => Если бы я передавал данные из MainPage в ChildPage, я бы отправлял данные в конструкторе. Но я хочу получить данные из Childpage в MainPage. Так что у PopAsyn c нет конструктора. Я также пробовал EventHandler, но он не работает.

Является ли единственным решением Центр сообщений? Или что вы посоветуете для лучшей производительности? Также MessagingCenter снижает производительность из-за высокого использования оперативной памяти? ПРИМЕЧАНИЕ: (Я хочу изучить архитектуру mvvm, поэтому я не хочу использовать другие фреймворки MVVM. Я хочу получить полное представление о MVVM и C#.) Заранее спасибо

Ответы [ 2 ]

1 голос
/ 15 января 2020

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

Если вы не хотите использовать центр обмена сообщениями, вы можете использовать инфраструктуру MVVM, которая имеет и другие преимущества. Я использую Prism для упрощения навигации, и вы можете передавать параметры навигации вместе.

Наконец, и обычно это не лучший вариант, вы можете хранить данные в объекте App. Вы можете установить значения в коллекции свойств. Это не рекомендуется для сложных объектов.

EDIT Сначала у вас будет некоторый объект передачи данных, который будет содержать ObservableCollection, если только вы не держите целые числа или что-то в этом роде.

public class MyDTO
{
  //fields for Data Transfer Object  
}

DTO часто входят в ваши модели, но иногда вам нужен составной класс для хранения DTO и коллекций DTO

Вот простая модель, которая будет содержать вашу ObservableCollection

public class MyCollectionModel
{
    #region Singleton Pattern
    private MyCollectionModel()
    {
    }
    public static MyCollectionModel Instance { get; } = new MyCollectionModel();
    #endregion
    private ObservableCollection<MyDTO> _dtos;
    public ObservableCollection<MyDTO> MyObservableCollection
    {
        get { return _dtos; }
        set { _dtos = value; }
    }
}

Обратите внимание, что это реализует шаблон Singleton. Это может даже повлиять на INotifyPropertyChanged.

Затем ваши модели представлений, представьте MyVM1 и MyVM2, будут ссылаться на ObservableCollection в вашей модели с чем-то вроде этого.

    public class MyVM1 : INotifyPropertyChanged // Do the same with MyVM2, which would be the binding context for view 2
    {
        private MyCollectionModel _model;
        public MyVM1 ()
        {
            _model = MyCollectionModel.Instance;
        }
        private ObservableCollection<MyDTO> myVar;
        public ObservableCollection<MyDTO> MyProperty //Bind to this in your View1
        {
            get 
            { 
                return _model.MyObservableCollection; 
            }
            set
            {
                myVar = value;
                NotifyPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Я ухожу здесь довольно много вещей, и на самом деле у меня нет времени на создание всего проекта только для тестирования. Надеюсь, это поможет.

0 голосов
/ 14 января 2020
  1. Обычно вы используете await navService.PushAsync(new MyPage2(dataToShare)); для передачи данных между страницами / виртуальными машинами. Это предполагает использование конструкторов. Вот простой пример этого: { ссылка }

  2. Поскольку вы не хотите использовать конструкторы, вы можете загрузить данные на своей дочерней странице с вашего служба. Кроме того, вы можете кэшировать данные в локальном хранилище (на стороне клиента) и просто загрузить их оттуда на своей дочерней / главной странице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...