Загрузка подпредставлений с MVP - PullRequest
8 голосов
/ 30 июня 2009

Последние пару дней я играл с паттерном MVP, используя winforms, но есть только одна вещь, которую я не знаю, как это сделать. Как вы создаете подчиненную форму из другого представления. Это будет действительный вариант.

 public class MyForm : IMainFormView
    {
        private MainFormPresenter pres;
        public MyForm() { pres = new MainFormPresenter(this); }

        //Event from interface.
        public event EventHandler<EventArgs> LoadSecondForm;

        public void SomeButtonClick()
        {
            LoadSecondForm(this, EventArgs.Empty);
        }
    }

    public class MainFormPresenter
    {
        private IMainFormView mView;

        public MainFormPresenter(IMainFormView view) {
            this.mView = view;
            this.Initialize();
        }

        private void Initialize() {
            this.mView.LoadSecondForm += new EventHandler<EventArgs>(mView_LoadSecondForm);
        }


        private void mView_LoadSecondForm(object sender, EventArgs e) {
            SecondForm newform = new SecondForm(); //Second form has its own Presenter.
            newform.Load(); // Load the form and raise the events on its presenter.
        }
    }

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

Спасибо.

Ответы [ 3 ]

8 голосов
/ 01 июля 2009

http://www.rickardnilsson.net/post/The-Humble-dialog-v2.aspx

Ссылка выше является наиболее близкой к этому ответу. Большинство попыток решить эту проблему оставляет желать лучшего.

2 голосов
/ 04 июля 2009

Взгляните на этот другой ТАК вопрос . Хотя это относится к WPF, а не к WinForms, проблема, похоже, та же.

По сути, я считаю необходимым показать вспомогательное окно Сервис (вы можете назвать его WindowsService или DialogService или что-то в этом роде). Это помогает вам взглянуть на вещи в перспективе, потому что, как только вы осознаете это, инъекция зависимости становится ответом.

В своем ответе вы моделируете это с помощью событий, но я предпочитаю более явную модель, в которой вы вызываете метод ShowDialog в DialogService. Тем не менее, механика каждого подхода не так уж отличается.

1 голос
/ 08 июля 2009

Пара комментариев к этому

Сначала это

    private void mView_LoadSecondForm(object sender, EventArgs e) {
        SecondForm newform = new SecondForm(); //Second form has its own Presenter.
        newform.Load(); // Load the form and raise the events on its presenter.
    }

Что произойдет, если вы решите заменить ThirdForm на SecondForm? Вам нужно найти каждый вызов newform = new SecondForm и внести изменения.

Вместо этого вы должны обернуть создание SecondForm в объект Command

   public class CreateSecondForm : ICommand
    {

        public void Execute() {
            SecondForm newform = new SecondForm(); //Second form has its own Presenter.
            newform.Load(); // Load the form and raise the events on its presenter.
        }

    }

Тогда здесь и в любом другом месте, где появляется вторая форма, используется этот синтаксис

private void mView_LoadSecondForm(object sender, EventArgs e) {
    CreateSecondForm createCmd = new CreateSecondForm(); 
    createCmd.Execute(); // Load the form and raise the events on its presenter.
}

Если вы хотите заменить совершенно новую форму для SecondForm, у вас есть только одно место, куда вам нужно перейти. Если вы хотите передать значения состояния или настройки, используйте конструктор команды. Вы даже можете передать другого Presenter или View и заставить команду извлечь информацию из его интерфейса.

Еще одна вещь, которую я рекомендую, - зарегистрировать формы, реализующие ваши представления, вместо использования новой команды. Это делается во время инициализации, и реестр отключается от вашего основного класса приложения.

Например.

public class MySecondForm : ISecondFormView, IViewForm
    {
        //Stuff ....
       Public ViewFormEnum ViewFormType {
          return ViewFormEnum.SecondForm;
       }
        //Stuff ....
    }

в другом месте программного обеспечения

public void InitializeApp() {
        //Stuff ....
        MyApp.ViewForm.Add(new MySecondForm);

        //Stuff ....

}

Затем команда настраивается следующим образом.

   public class CreateSecondForm : ICommand
    {
        myApp theApp;
        public CreateSecondForm(myApp thisApp) {
           theApp = thisApp;
        }

        public void Execute() {
            SecondForm newform = theApp.Find(ViewFormEnum.SecondForm);
            if (newForm != null) 
               newform.Load(); // Load the form and raise the events on its presenter.
        }

    }

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

Хотя я настоятельно рекомендую вам использовать команду, чтобы завершить создание ваших просмотров. Второе предложение о регистрации View может быть излишним в зависимости от приложения. В моем приложении CAD / CAM у меня есть десятки диалогов и несколько различных основных форм, используемых для различных аспектов настройки и управления двухмерным металлорежущим столом. Однако в некоторых других приложениях моей компании я использую простой подход, поскольку в основном это простые утилиты.

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