Как выставить свойства пользовательского элемента управления в .NET для шаблона MVP - PullRequest
2 голосов
/ 30 сентября 2011

Я реализую простой UserControl, который на самом деле просто фантастический TextBox. Одной из его особенностей является то, что вы можете установить спецификацию форматирования, и это форматирование будет автоматически применено к его содержимому. Например, если для спецификации форматирования задано значение "000", а для содержимого - "42", появится "042".

Я реализую это UserControl по шаблону MVP. Реализация похожа на это: Как реализовать usercontrol в шаблоне winforms mvp? . Также проверьте этот вопрос: пассивное представление и логика отображения

Подход № 1

Мое Title свойство в View выглядит следующим образом:

private string title;
public string Title {
    get { return title; }
    set { title = value; titleTextBox.Text = presenter.Format(title); }
}

Мне кажется, что эта реализация добавляет ненужную связь. Например, если я изменю метод Presenter Format, мне придется пройти через все View s и соответствующим образом изменить оператор вызова.

Подход № 2

Свойство Title в View выглядит следующим образом:

public string Title {
    get { return presenter.Title; }
    set { presenter.Title = value; }
}

Свойство Title в Presenter выглядит следующим образом:

private string title;
public string Title {
    get { return title; }
    set { _view.SetTitle(this.Format(value); }
}

Теперь мне нужно добавить метод SetTitle в интерфейсе View и в реализации View:

public void SetTitle(string title) {
    titleTextBox.Text = title;
}

Итак, при таком подходе я получаю этот уродливый SetTitle Java-подобный метод.

Подход № 3

Вместо вызова SetTitle создайте новое свойство RealTitle в View и установите его. С этим Real префиксом уродливо.

Ваш подход

Можете ли вы придумать лучший способ?

Вариант использования

UserControl следует использовать так:

var c = new FancyTextBox();
c.Format = "000";
c.Text = "42";
Controls.Add(c);

Этот фрагмент должен отображать "042" внутри UserControl.

Большая картинка

Form            FancyTextBoxView             FancyTextBoxPresenter
  |                     |                              |
  |  ftb.Text = "42"    |                              |
  |-------------------->|                              |
  |                     |                              |
  |                     |              A               |
  |                     |----------------------------->|
  |                     |                              |
  |                     |              B               |
  |                     |<-----------------------------|

Что такое действия A и B? Я хочу, чтобы отформатированный текст отображался в пользовательском интерфейсе. Код форматирования находится в Presenter. View имеет titleTextBox, который будет содержать текст в пользовательском интерфейсе.

Ответы [ 2 ]

2 голосов
/ 30 сентября 2011

Почему бы вам просто не определить свойство заголовка вашего вида следующим образом?

public string Title {
    get { return titleTextBox.Text; }
    set { titleTextBox.Text = value; }
}

Нет абсолютно никаких причин для определения дополнительного метода SetTitle. Кроме того, в MVP ваше мнение никогда не должно знать о вашем докладчике.

Затем, когда сработает ваша функция Format, вы можете установить оттуда заголовок вашего представления, например:

void OnFormatCalled()
{
   _view.Title = FormatTitle(_view.Title);
}
1 голос
/ 30 сентября 2011

Я обычно внедряю интерфейс View (и интерфейс Model) в Presenter. Теперь вам нужно беспокоиться о зависимостях и тестировании.

Пусть ваш взгляд запускает событие, когда заголовок установлен, и ваш Presenter подписывается на него. Затем докладчик может отформатировать текст и установить заголовок в представлении - докладчик отвечает за представление представления, представление просто отображает данные. Таким образом, представление действительно глупо с небольшой логикой вообще. Это позволяет использовать его во время модульного тестирования и делает докладчика действительно простым в тестировании.

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

public class Presenter
{
   private IView _view;
   private IModel _model;

   public Func<string, string> TitleFormatter { get; set; }

   public Presenter(IView view, IModel model)
   {
      _model = model;
      _view = view;

      _view.OnSetTitle += (s, e) => {
          _view.Title = TitleFormatter(e.Text);
       };
   }
}

public View : IView
{
    public event EventHandler<TitleChangedEventArgs> TitleChanged;

    public SomeUserActionEvent(object sender, SomeUserInterfaceEventArgs e)
    {
       TitleChanged(e.Text);
    }
}
...