MVVM - Должно ли Представление содержать ссылку на Presenter / ViewModel?

StackOverflow https://stackoverflow.com/questions/1431758

  •  07-07-2019
  •  | 
  •  

Вопрос

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

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

    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();
    }
}

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

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

Решение

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

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

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

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

-Jer

Другие советы

Наиболее распространенный подход к сопоставлению ViewModel с представлением в MVVM заключается в использовании DataTemplate :

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top