MVVM Light, Windows Phone, View & ViewModel навигация между страницами - PullRequest
4 голосов
/ 20 июля 2011

У меня есть страница, на которой вы в основном выбираете набор параметров (конфигурацию), а затем вы переходите на следующую страницу, где вы что-то делаете
Используя инструментарий MVVM Light, у меня есть модель представления, которая привязывается кпросмотр первой страницы.когда пользователь нажимает кнопку, он перенаправляет на другое представление, которое будет 2-й страницей, т.е.пара параметров в конструкторе, которые в основном являются зависимостями от конфигурации, которая была задана на первой странице.

т.е.:

public DoStuffViewModel(ICollection<Note> availableNotes, SoundMappers soundType)
{
}

Проблема заключается здесь .. Как я могу создать экземплярмодель представления с этими данными, которая была динамически выбрана пользователем на 1-й странице?.
Я не могу использовать шаблон ViewModelLocator, который предоставляет свет MVVM, так как эти модели представления не имеют никаких зависимостей, они просто сами по себе (или они могут извлекать данные из базы данных, файла или чего-либо еще, но у них нет динамических входных данных).Я мог бы сделать это через конструктор представления, создать там экземпляр модели представления и назначить источнику данных представления вновь созданную модель представления, но я думаю, что это не очень хорошо делать.предложения?

Ответы [ 3 ]

3 голосов
/ 20 июля 2011

Как я вижу, вы отправляете сообщения с помощью класса Messenger, так что вы знакомы с сообщениями в свете MVVM.Вы должны определить свой собственный тип сообщения, который должен принимать ваши параметры со страницы 1:

    public class Page2ViewModelCreateMessage : MessageBase
{
    public ICollection<Note> AvailableNotes{get;set;}
    public SoundMappers SoundType{get;set;}

    public Page2ViewModelCreateMessage ()
    {

    }

    public Page2ViewModelCreateMessage(ICollection<Note> availableNotes, SoundMappers soundType)
    {
        this.AvailableNotes = availableNotes;
        this.SoundType = soundType;
    }
}

Вы должны отправить экземпляр Page2ViewModelCreateMessage с вашими параметрами и отправить его при навигации:

var message = new Page2ViewModelCreateMessage(myAvailableNotes, mySoundType)
Messenger.Default.Send(message);

На Page2 вы должны зарегистрироваться для получения сообщения типа Page2ViewModelCreateMessage:

        Messenger.Default.Register<Page2ViewModelCreateMessage>(this, OnPage2ViewModelCreateMessage);
    ..
    public void OnPage2ViewModelCreateMessage(Page2ViewModelCreateMessage message)
    {
        var page2ViewModel = new Page2ViewModel(messsage.AvailableNotes, message.SoundType);
    }   

Как вы можете видеть, я должен заменить вашу DoStuffViewModel на Page2ViewModel, чтобы быть более понятным.

Я надеюсь, что это поможетВы.

ПРИМЕЧАНИЕ. Я не гарантирую, что код будет работать так, как написано в блокноте.

1 голос
/ 20 июля 2011

Способ, которым я это делаю, - это иметь класс центрального контроллера, о котором все ViewModels знают, через интерфейс.Затем я устанавливаю это состояние перед тем, как телефон выполнит навигацию за меня.Затем каждая ViewModel опрашивает этот центральный класс для нужного ему состояния.

Для меня есть ряд преимуществ:

  • Это позволяет мне иметь нестатические ViewModels.
  • Я могу использовать Ninject, чтобы внедрить конкретную реализацию класса контроллера и определить его как единичный объект.
  • Самое главное, что при захоронении нужно только захватить текущую ViewModel и класс контроллера.

Я столкнулся с проблемой обмена сообщениями, когда мой ViewModel был зарегистрированным слушателем, потому что я был View First, а не ViewModel First, я был вынужден использовать статические ссылки ViewModel.В противном случае ViewModel не был создан вовремя для получения сообщения.

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

Если подумать, класс контроллера - это тоже мой приемник навигации - так как у меня есть некоторый пользовательский код навигации, который пропускает переход по страницам на определенных страницахи т. д.

Вот пример моей текущей настройки:

public interface IController
{
    Foo SelectedFoo { get; }
}

public class ViewModel
{
    private IController _controller;

    public ViewModel(IController controller)
    {
        _controller = controller;
    }

    private void LoadData()
    {
        // Using selected foo, we load the bars.
        var bars = LoadBars(_controller.SelectedFoo);
    }
}
0 голосов
/ 28 мая 2014

Вы можете использовать словарь PhoneApplicationService для сохранения данных, которые вам нужны при навигации по первому событию, и анализировать их при переходе ко второй странице.Вы также можете использовать эти данные в ваших ViewModels.Примерно так:

 PhoneApplicationService.Current.State["DatatFromFirstPage"] = data;

и при переходе на вторую страницу:

 if (PhoneApplicationService.Current.State.ContainsKey("DatatFromFirstPage"))
 {
      var dataUsedOnSeconPage= PhoneApplicationService.Current.State["DatatFromFirstPage"];
 }

вы можете использовать эти данные глобально во всем приложении

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