MVVM - Должен ли вид иметь ссылку на Presenter / ViewModel? - PullRequest
0 голосов
/ 16 сентября 2009

Я просматривал образцы PRISM 2, чтобы найти идеи о том, как лучше всего подойти к новому приложению, над которым я работаю, - приложению PRISM 2 / WPF. Рассматривая, в частности, пример приложения View Injection, которое поставляется с PRISM, я заметил, что все представления реализуют интерфейс, который позволяет докладчику (или ViewModel) взаимодействовать с представлением.

В прошлом я делал это наоборот, я вставлял докладчика в представление, чтобы представление могло напрямую вызывать методы в презентаторе примерно так:

    public partial class SomeView : ModuleBase
    {

        private ISomePresenter _somePresenter;

        public SomeView (ISomePresenter somePresenter):this()
        {
            // Give the view a reference to the presenter
            _somePresenter = somePresenter;
            // Bind the View to the presenter
            DataContext = _somePresenter;
        }

    private void btnSubmit_Click(object sender, RoutedEventArgs e)
    {
        // The view can call actions directly on the presenter (OK I should probably use a command for this)
        _somePresenter.SomeAction();
    }
}

Приведенная выше техника показалась мне достаточно разумной, но, глядя на примеры, я начинаю подвергать сомнению подход. У кого-нибудь есть взгляды (без каламбура) на лучший способ сделать это?

  • Добавьте докладчика к представлению и получите представление для взаимодействия с докладчиком
  • Добавьте представление к докладчику и заставьте докладчика взаимодействовать с представлением
  • Что-то совершенно другое, о чем я еще не думал?

Ответы [ 2 ]

5 голосов
/ 17 сентября 2009

Наиболее распространенный подход для сопоставления ViewModel с View в MVVM - это использование DataTemplate:

<DataTemplate DataType="{x:Type vm:SomeViewModel}">
    <v:SomeView />
</DataTemplate>

Когда вы отображаете экземпляр ViewModel в ContentControl или ItemsControl, WPF автоматически создает экземпляр соответствующего View для ViewModel и устанавливает DataContext View для экземпляра ViewModel.

Таким образом, у вас нет ссылки на View в ViewModel, а View ссылается только на ViewModel через свойство DataContext. В случае, если вам действительно нужен доступ к ViewModel в кодовой части View, вы всегда можете привести DataContext (но это означает, что View знает о фактическом типе ViewModel, который вызывает соединение)

2 голосов
/ 17 сентября 2009

Я думаю, это все дело вкуса. Лично мне нравится, как вы видите это в образцах, на которые вы смотрите. У IView есть один метод - SetViewModel (...). IViewModel имеет свойство View типа Object, которое, по существу, возвращает экземпляр IView, созданный DI.

Причина, по которой мне нравится этот способ, заключается в том, что я почти всегда хочу сначала создать ViewModel, и я хочу, чтобы nobody в коде мог делать что-либо с моим IView, кроме получения ссылки на экземпляр ( представление внедрения или привязка представления, например, ContentControl), поэтому он имеет тип объекта. Если какой-либо код должен взаимодействовать с представлением, для меня это всегда через виртуальную машину ... и даже тогда представление обновляется обычно через связывание. Было бы странно перейти из View-> ViewModel-> UpdateBinding-> View, чем VM-> UpdateBinding-> View

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

Как я уже сказал, все дело вкуса ...

-Jer

...