2010-08-04 171 views
1

我有一个类似于下图的窗口的应用程序。GUI设计模式,MVP,标签控件

alt text http://a.imageshack.us/img137/7481/screenshotxh.jpg

这里的要求是,当用户点击保存按钮,一切都得到保存。 “保存”和“重置”按钮对所有选项卡“通用”。因此,当选择“个人信息”选项卡并单击“保存”时,程序还应保存“朋友”选项卡中所做的更改以及“就业历史记录”选项卡中所做的更改。

该应用程序已经为下面的代码,我想保持这种代码:

-PersonalInformationView,PersonalInformationPresenter,PersonalInformationModel

-FriendsView,FriendsPresenter,FriendsModel

-EmploymentHistoryView,EmploymentHistoryPresenter,EmploymentHistoryModel

每个演示者有一个保存方法。

问题是什么是一个好的设计模式,考虑到我想保留我已经拥有的代码。另外,我希望这个窗口有模型,视图,主持人。或者,也许我应该改写一下我的问题:当编程MVP时,包括“子视图”,“子演示者”的最佳方式是什么?

问候, MadSeb

回答

0

我会让你的新主持人拿在副主持人构造函数的参数,是这样的:

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

当然如果您的主持人有他们之间的通用接口,这可以简化(并使其更加可扩展),像这样:

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

编辑: 调用代码将是someth荷兰国际集团这样的:

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

希望这是一些inpsiration /帮助:)

+0

这确实提供了一些启发。但是,我有以下问题。 每个演示者的“保存”方法在保存之前进行数据验证,万一它失败*调用view.DisplayValidationErrors()*并显示msgbox(“邮政编码丢失”等) 如果我选择使用代码你建议用户将得到一个msg.box的第一个选项卡中的验证错误,一个msg.box的第二个选项卡中的验证错误..但我想所有的验证错误汇总在一个msg.box。 – MadSeb 2010-08-05 19:16:27

+0

我已经更新了我的答案(第二个代码块)以显示我如何处理这个问题 – Pondidum 2010-08-12 06:40:35

1

我个人建议作出的抽象接口,ISaveable,或osmething并确保每个主持人的实现这一点,不是通过每一个主持人作为ISaveable的对象,并保存每一个。

+0

..但是从“主视图”的主持人,我没有获得的“子视图的主持人“(PersonalInformationView,FriendsView,EmploymentHistoryView)..我只能访问”子视图“本身... – MadSeb 2010-08-04 13:43:16

0

我的建议是用save方法创建ISaveableView。 您的每个视图都将实现该界面。 我猜你的选项卡实现了你所描述的视图。当您单击保存按钮,就可以把有源标签来ISaveableView并调用它的保存方法

+0

嗨,这是一个很好的回应,但”保存“方法不是视图的一部分,但是主讲人的一部分。 ........但我想我可以在视图中制作一个“保存”方法,这种方法会调用演示者的“保存”。 – MadSeb 2010-08-04 13:41:11