Lead presenter and repeater

I am creating an application using Supervising Controller (Model View Presenter) pattern and I am facing difficulties. On my page, I have a relay control that will display every item in the collection that I navigate to. The reapeater element contains 2 dropdowns that allow the user to select a specific value. When I click the next button, I want the controller to fetch these values.

How can I do this in a clean way?

+1


source to share


2 answers


You can also create a "widget" interface for the dropdown. I'll give you a simple example of some working code for a TextBox widget to get you the 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; }
}

      

Note that everything is technology agnostic so far. Now here is the implementation for the 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; }
    }
}

      

This gets an instance in the Form itself, which is returned in the MVP also in IViewWhatever:



public partial class ProjectPickerForm : Form, IProjectPickerView
{

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

      

And in the Host:

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

      

It looks worse than it does for customization because most of the work is pretty mechanical once you get the idea. The clean part is that the presenter can get (and set) whatever information he wants in the widgets without knowing or caring what the implemented widget is. It also allows you to reuse other widgets (you create a library of them) of the same type (Win Forms here) and in other UI technologies (if you have an interface / base class, implementation in another technology is trivial). It's also easy to test with mocks because you have an interface. And your user interface is now perfectly aware of everything except the tasks associated with the user interface.The downside is a bunch of classes for each widget and a little learning curve to keep them comfortable.

For your dropdown, you may need an event of type SelectedIndexChanged, which you would replace with this TextChanged event.

+2


source


When interacting with the controller view gets too complicated, I usually split them into sub-controllers and sub-views.

You can have items in a relayer - custom controls that have their own views and controllers. Your main view may have a list of subtasks (usercontrols) that have their own controllers that are supported by the main controller.



When the user clicks the mouse, your main controller can signal all subcontrollers to update their items from their views.

+1


source







All Articles