开发者

GUI Design Pattern , MVP, Tab Control

开发者 https://www.devze.com 2023-01-10 00:04 出处:网络
I have an application that has a window similar to the one bellow . alt text http:开发者_如何学C//a.imageshack.us/img137/7481/screenshotxh.jpg

I have an application that has a window similar to the one bellow .

alt text http:开发者_如何学C//a.imageshack.us/img137/7481/screenshotxh.jpg

The requirement here is that when the user clicks the Save button everything has to get saved. The "Save" and "Reset" buttons are "common" to all tabs. Hence, when the "Personal Information" tab is selected and "Save" is clicked the program should also save changes made in the "Friends" tab and changes made in the "Employment History" tab.

The app already has code for the following and I want to keep this code:

-PersonalInformationView , PersonalInformationPresenter, PersonalInformationModel

-FriendsView, FriendsPresenter, FriendsModel

-EmploymentHistoryView, EmploymentHistoryPresenter, EmploymentHistoryModel

Each presenter has a Save method.

The question is what would be a good design pattern to use taking into consideration that I want to keep the code I already have. Also, I want this window to have model, view, presenter as well. Or maybe I should rephrase my question a bit: what's the best way of including "sub-views", "sub-presenters" when programming MVP ?

Regards, MadSeb


I personally would suggest making an abstract interface, ISaveable, or osmething and ensure that each of the presenters implement this, than go through each presenter as an object of ISaveable and save each one.


I would make your new presenter take in your sub presenters as constructor arguments, something like:

class DialogPresenter {

    private readonly IDialogView view;
    private readonly PersonalInformationPresenter personal;
    private readonly FriendsPresenter friends;
    private readonly EmploymentHistoryPresenter history;

    void DialogPresenter(IDialogView view, PersonalInformationPresenter personal, FriendsPresenter friends, EmploymentHistoryPresenter history) {
        this.view = view;
        this.personal = personal;
        this.friends = friends;
        this.history = history;
    }

    bool Display() {
        this.personal.Display();
        this.friends.Display();
        this.history.Display();

        return this.view.Display() == DialogResult.Ok;
    }

    void Save() {
        this.personal.Save();
        this.friends.Save();
        this.history.Save();
    }
}

Of course, if your presenters had a common interface between them, this could be simplified (and made more extendable) like so:

class DialogPresenter {

    private readonly IDialogView view;
    private readonly IPresenters[] presenters;

    void DialogPresenter(IDialogView view, IPresenters[] presenters)
    {
        this.view = view;
        this.presenters = presenters;
    }

    bool Display() {
        foreach (var item in this.presenters)
            item.Display();

        return this.view.Display() == DialogResult.Ok;
    }

    void Save() {
        var validation = new List<string>();

        foreach (var item in this.presenters)
            validation.AddRange(item.Validate());

        if (validation.Count > 0) {
                _view.ShowErrors(validation);
                return;
        }

        foreach (var item in this.presenters)
            validation.AddRange(item.Save());
    }
}

Edit: Calling code would be something like this:

void DisplayForm() {

    using (var frm = new frmDisplay) {

        //or just use DI to get the models etc
        var personal = new PersonalInformationPresenter(personalModel, frm.PersonalTab);    //some properties to expose your views
        var friends = new FriendsPresenter(friendslModel, frm.FriendsTab);
        var history = new EmploymentHistoryPresenter(employmentHistoryModel, frm.HistoryTab);

        var presenter = new DialogPresenter(frm, personal, friends, history);
        if (presenter.Display()) {    
            presenter.Save();
        }
    }
}

Hope that is of some inpsiration/help :)


My suggestion is to create ISaveableView with save method. Each of your views will implement the interface. I am guessing that your tabs implements the views you've described. When you click the save button you can cast the active tab to ISaveableView and call its save method

0

精彩评论

暂无评论...
验证码 换一张
取 消