2008-11-06 9 views
1

Я создаю приложение с использованием шаблона диспетчерского контроллера (Model View Presenter), и я сталкиваюсь с трудностями. На моей странице у меня есть элемент управления ретранслятора, в котором будет отображаться каждый элемент коллекции, к которой я перехожу. Элемент reapeater содержит 2 раскрывающихся списка, которые позволяют пользователю выбирать конкретное значение. Когда я нажимаю следующую кнопку, я хочу, чтобы контроллер извлекал эти значения.Model View Presenter and Repeater

Как я могу это сделать чистым способом?

+0

На каком языке вы создали свое приложение? – 2016-06-28 13:03:30

ответ

2

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

public interface ITextWidget 
{ 
    event EventHandler TextChanged; 
    string Text { get; set; } 
} 

public abstract class TextWidget<T> : ITextWidget 
{ 

    protected T _wrappedWidget { get; set; } 
    public event EventHandler TextChanged; 

    protected void InvokeTextChanged(object sender, EventArgs e) 
    { 
     var textChanged = TextChanged; 
     if (textChanged != null) textChanged(this, e); 
    } 

    public abstract string Text { get; set; } 
} 

Обратите внимание, что до сих пор все является агностиком. Теперь вот реализация для Win Forms TextBox:

public class TextBoxWidget : TextWidget<TextBox> 
{ 

    public TextBoxWidget(TextBox textBox) 
    { 
     textBox.TextChanged += InvokeTextChanged; 
     _wrappedWidget = textBox; 
    } 

    public override string Text 
    { 
     get { return _wrappedWidget.Text; } 
     set { _wrappedWidget.Text = value; } 
    } 
} 

Это получает экземпляр в самой форме, которая обратно MVP является также IViewWhatever:

public partial class ProjectPickerForm : Form, IProjectPickerView 
{ 

    private IProjectPickerPresenter _presenter; 
    public void InitializePresenter(IProjectPickerPresenter presenter) { 
     _presenter = presenter; 
     _presenter.InitializeWidgets(
      ... 
      new TextBoxWidget(txtDescription)); 
    } 
      ... 
} 

И в Presenter:

public class ProjectPickerPresenter : IProjectPickerPresenter 
{ 
    ... 
    public void InitializeWidgets(ITextWidget descriptionFilter) { 

     Check.RequireNotNull<ITextWidget>(descriptionFilter, "descriptionFilter"); 
     DescriptionFilter = descriptionFilter; 
     DescriptionFilter.Text = string.Empty; 
     DescriptionFilter.TextChanged += OnDescriptionTextChanged; 

    } 
    ... 

    public void OnDescriptionTextChanged(object sender, EventArgs e) { 
     FilterService.DescriptionFilterValue = DescriptionFilter.Text; 
    } 

Это выглядит хуже, чем настройка, потому что большая часть работы достаточно механическая, как только вы получите эту идею. Чистая часть состоит в том, что ведущий может получить (и установить) любую информацию, которая ему нужна в виджетах, не зная или не заботясь о том, что представляет собой реализованный виджет. Он также позволяет повторно использовать другие виджеты (вы создаете их библиотеку) того же типа (Win Forms здесь) и в других технологиях пользовательского интерфейса (если у вас есть интерфейс/базовый класс, реализация в другой технологии тривиальна). Он также легко тестируется с помощью mock-объектов, потому что у вас есть интерфейс. И ваш пользовательский интерфейс теперь прекрасно осведомлен обо всем, кроме задач, связанных с пользовательским интерфейсом. Недостатком является куча классов для каждого виджета и небольшая кривая обучения, чтобы им было удобно.

Для вашего раскрывающегося списка вам может понадобиться событие типа SelectedIndexChanged, которое вы заменили бы для этого примера событие TextChanged.

1

Когда взаимодействие с представлением контроллера слишком сложное, я обычно разбиваю их на субконтроллеры и подсмотры.

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

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