2010-08-04 3 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 것 같이 보내고 : 일부 inpsiration/도움말 :이다

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

희망

+0

이것은 참으로 영감을줍니다. 그러나, 다음과 같은 문제가 있습니다. 각 발표자의 "저장"방법은 저장하기 전에 데이터 유효성 검사를 수행하며 실패 할 경우 * view.DisplayValidationErrors() *가 호출되고 msgbox가 표시됩니다 ("우편 번호가 없습니다."등) 당신이 제안한 코드는 첫 번째 탭의 유효성 검사 실수에 대해 하나의 msg.box, 두 번째 탭의 유효성 검사 실수를위한 msg.box 하나를 얻을 것을 제안했습니다. 그러나 모든 유효성 검사 실수는 단지 하나의 msg.box에 집계됩니다. – MadSeb

+0

나는 이것을 처리하는 방법을 보여주기 위해 나의 대답 (두 번째 코드 블록)을 업데이트했다. – Pondidum

1

나는 개인적으로 추상적 인 인터페이스, ISaveable, 또는 osmething을 제안하고 ISaveable의 대상으로 각 발표자를 통과하고 각각을 저장보다 발표자의 각이 구현되도록한다.

+0

..하지만 "메인 뷰 '의 발표자에서 나는"하위 뷰의 발표자에 액세스 할 수 없습니다 "(PersonalInformationView, FriendsView, EmploymentHistoryView) .."하위보기 "자체에만 액세스 할 수 있습니다 ... – MadSeb

0

내 제안은 save 메서드를 사용하여 ISaveableView를 만드는 것입니다. 각보기가 인터페이스를 구현합니다. 귀하의 탭이 귀하가 묘사 한 견해를 구현하고 있다고 생각합니다. 당신이 (가) 저장 버튼을 클릭하면 당신은 ISaveableView에 활성 탭을 던져 내가 생성자 인자, 뭔가 등 당신의 서브 발표자에 새 발표자 테이크를 만들 것

+0

안녕하세요, 이것은 좋은 응답이지만"저장 "방법은보기의 일부가 아니라 발표자의 일부입니다. ........하지만 난보기에서 "저장"메서드를 만들 수 있으며이 메서드는 발표자의 "저장"전화 것이라고 생각합니다. – MadSeb