Model View Presenter e Repeater
-
06-07-2019 - |
Pergunta
Estou construindo uma aplicação usando o padrão Controlador de Supervisão (Model View Presenter) e eu estou enfrentando uma dificuldade. Na minha página eu tenho um controle de repetidora que irá exibir cada item de uma coleção que eu estou passando para ele. O item reapeater contém 2 lista suspensa que permite que o usuário selecione um valor particular. Quando clico no botão ao lado, eu quero o controlador para recuperar esses valores.
Como posso fazer que eu uma maneira limpa?
Solução
Você também pode fazer um 'Widget' interface para o drop-down. Vou te dar um exemplo fácil de um algum código trabalhando para um widget de caixa de texto para que você começa a idéia.
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; }
}
Observe que até agora tudo é tecnologia agnóstico. Ora aqui está uma implementação para um 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; }
}
}
Esta é instanciado no próprio formulário, que volta para MVP é também o IViewWhatever:
public partial class ProjectPickerForm : Form, IProjectPickerView
{
private IProjectPickerPresenter _presenter;
public void InitializePresenter(IProjectPickerPresenter presenter) {
_presenter = presenter;
_presenter.InitializeWidgets(
...
new TextBoxWidget(txtDescription));
}
...
}
E no 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;
}
É Parece pior do que é a configuração porque a maioria do trabalho é bastante mecânica uma vez que você começa a idéia. A parte limpa é que o apresentador pode obter (e definido) qualquer informação precisa sobre o widget sem saber ou se importar que o real implementado widget é. Ele também se presta a reutilização com outros widgets (você acaba construindo uma biblioteca deles) do mesmo tipo (Win Forms aqui) e em outras tecnologias de interface do usuário, conforme necessário (uma vez que você tem a classe de interface / base a implementação de outra tecnologia é trivial). Também é fácil de teste com objetos fictícios porque você tem a interface. E sua interface é agora maravilhosamente ignorantes de quase tudo, mas tarefas relacionadas UI. A desvantagem é o monte de aulas por widget e um pouco de curva de aprendizagem para se sentir confortável com ele.
Para a sua queda para baixo, seu poder só precisa do tipo de evento SelectedIndexChanged, que você iria substituir este exemplos TextChanged evento.
Outras dicas
Quando o controlador-view interação get é demasiado complexo eu costumo dividi-los em subcontroladores e subviews.
Você pode ter os itens do repetidor ser user-controles que têm os seus próprios pontos de vista e os controladores. Sua vista principal pode então ter uma lista de subviews (usercontrols) que têm seus próprios controladores que são mantidos pelo controlador principal.
Quando o usuário clica no próximo seu controlador principal pode sinalizar todos os subcontroladores para atualizar seus itens de seus pontos de vista.