Search code examples
c#winformsdesign-patternsmvp

How to set control state in MVP


I want to disable button(or other control) when user can't raise event. What is the best way to do this? View handles that or presenter should pass value by property in view and then view will update control's state.

For example if previous query is not finished user shouldn't start new.

Option 1:

interface IView
{
    event EventHandler Event;
}

class View : IView
{
    private readonly Button _button;

    public event EventHandler Event;

    public void button_Click(object sender, EventArgs e)
    {
        _button.Enabled = false;

        if(Event != null)
        {
            Event(this, EventArgs.Empty);
        }

        _button.Enabled = true;
    }

}

class Presenter
{
    public void View_Event(object sender, EventArgs e)
    {
        // code...
    }
}

Option 2:

interface IView
{
    event EventHandler Event;

    bool CanRaiseEvent { set; }
}

class View : IView
{
    private readonly Button _button;

    public event EventHandler Event;

    public bool CanRaiseEvent
    {
        set
        {
            _button.Enabled = value;
        }
    }

    public void button_Click(object sender, EventArgs e)
    {
        if (Event != null)
        {
            Event(this, EventArgs.Empty);
        }
    }
}

class Presenter
{
    private readonly IView _view;
    public void View_Event(object sender, EventArgs e)
    {
        _view.CanRaiseEvent = false;

        // code...

        _view.CanRaiseEvent = true;
    }
}

I know that i should check in presenter query's status before executing next query but I want to inform view that user shouldn't even try.


Solution

  • Two 'litmus' tests I use for MVP design are: 1) Is the logic testable? and 2) Could I replace the concrete view and the application still work?

    From this perspective, option 2 looks the more attractive.