Domanda

Sto costruendo un'applicazione usando il modello Supervision Controller (Model View Presenter) e sto affrontando una difficoltà. Nella mia pagina ho un controllo ripetitore che mostrerà ogni elemento di una collezione che sto passando ad esso. L'elemento reapeater contiene 2 elenchi a discesa che consentono all'utente di selezionare un valore particolare. Quando faccio clic sul pulsante successivo, desidero che il controller recuperi tali valori.

Come posso farlo in modo pulito?

È stato utile?

Soluzione

Puoi anche creare un'interfaccia 'widget' per il menu a discesa. Ti darò un semplice esempio di un codice funzionante per un widget TextBox in modo da avere l'idea.

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

Si noti che finora tutto è indipendente dalla tecnologia. Ora ecco un'implementazione per un TextBox Win Forms:

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

Questo viene istanziato nel modulo stesso, che di nuovo a MVP è anche IViewWhatever:

public partial class ProjectPickerForm : Form, IProjectPickerView
{

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

E nel presentatore:

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

Sembra peggiore di quanto sia da configurare perché la maggior parte del lavoro è abbastanza meccanica una volta presa l'idea. La parte essenziale è che il relatore può ottenere (e impostare) qualsiasi informazione di cui abbia bisogno sul widget senza sapere o preoccuparsi di quale sia il widget effettivamente implementato. Si presta anche al riutilizzo con altri widget (finisci per crearne una libreria) dello stesso tipo (qui Win Forms) e in altre tecnologie dell'interfaccia utente secondo necessità (una volta che hai l'interfaccia / classe base l'implementazione in un'altra tecnologia è banale). È anche facile testare con oggetti finti perché hai l'interfaccia. E la tua interfaccia utente ora è meravigliosamente ignorante di tutto tranne che delle attività correlate all'interfaccia utente. Il rovescio della medaglia è il gruppo di classi per widget e una piccola curva di apprendimento per familiarizzare con esso.

Per il tuo menu a discesa, potresti semplicemente avere bisogno dell'evento di tipo SelectedIndexChanged, che sostituiresti con questo evento TextChanged di esempio.

Altri suggerimenti

Quando l'interazione con il controller diventa troppo complessa, di solito li divido in subcontrollori e sottoview.

È possibile impostare gli elementi nel ripetitore come controlli utente con proprie visualizzazioni e controller. La vista principale può quindi avere un elenco di viste secondarie (controlli utente) che hanno i propri controller gestiti dal controller principale.

Quando l'utente fa clic su successivo, il controller principale può segnalare a tutti i subcontroller di aggiornare i propri elementi dalle loro visualizzazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top