2010-08-04 169 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