2009-06-30 84 views
8

过去几天我一直在使用winforms玩MVP模式,只有一件事我不知道该怎么做。你如何从另一个视图创建子窗体。这是否是一个有效的选择。加载MVP的子视图

public class MyForm : IMainFormView 
    { 
     private MainFormPresenter pres; 
     public MyForm() { pres = new MainFormPresenter(this); } 

     //Event from interface. 
     public event EventHandler<EventArgs> LoadSecondForm; 

     public void SomeButtonClick() 
     { 
      LoadSecondForm(this, EventArgs.Empty); 
     } 
    } 

    public class MainFormPresenter 
    { 
     private IMainFormView mView; 

     public MainFormPresenter(IMainFormView view) { 
      this.mView = view; 
      this.Initialize(); 
     } 

     private void Initialize() { 
      this.mView.LoadSecondForm += new EventHandler<EventArgs>(mView_LoadSecondForm); 
     } 


     private void mView_LoadSecondForm(object sender, EventArgs e) { 
      SecondForm newform = new SecondForm(); //Second form has its own Presenter. 
      newform.Load(); // Load the form and raise the events on its presenter. 
     } 
    } 

我主要关心的是你将如何加载使用这种模式子窗体,你会怎么说,通过从第一页到子窗体的ID。

谢谢。

回答

2

看一看this other SO question。虽然它涉及到WPF而不是WinForms,但问题似乎是相同的。基本上,我认为需要显示一个子窗口的服务(你可以称之为WindowsService或DialogService或类似的东西)。这可以帮助你把事情看得透彻,因为只要你意识到,依赖注入就成了答案。

在你的答案中,你用事件建模了这个,但我更喜欢一个更明确的模型,你可以在其中调用DialogService的ShowDialog方法。然而,每种方法的机制都没有那么不同。

1

这个

首先一对夫妇的意见这

private void mView_LoadSecondForm(object sender, EventArgs e) { 
     SecondForm newform = new SecondForm(); //Second form has its own Presenter. 
     newform.Load(); // Load the form and raise the events on its presenter. 
    } 

,如果你决定替换ThirdForm为SecondForm会发生什么?您需要查找newform = new SecondForm的每个调用并进行更改。

相反,你应该换行SecondForm创建一个Command对象

public class CreateSecondForm : ICommand 
    { 

     public void Execute() { 
      SecondForm newform = new SecondForm(); //Second form has its own Presenter. 
      newform.Load(); // Load the form and raise the events on its presenter. 
     } 

    } 

然后在这里和其他地方带来了第二个形式使用该语法

private void mView_LoadSecondForm(object sender, EventArgs e) { 
    CreateSecondForm createCmd = new CreateSecondForm(); 
    createCmd.Execute(); // Load the form and raise the events on its presenter. 
} 

如果你想替补多一SecondForm完全新的形式,那么你只有一个你需要去的地方。如果您想传递状态或设置值,则使用该命令的构造函数。您甚至可以通过另一个Presenter或View,并让该命令从其界面中获取信息。

我推荐的另一件事是您注册实现您的意见,而不是使用新的命令的形式。这是在初始化过程中完成的,并且注册表挂起了主应用程序类。

例如。

public class MySecondForm : ISecondFormView, IViewForm 
    { 
     //Stuff .... 
     Public ViewFormEnum ViewFormType { 
      return ViewFormEnum.SecondForm; 
     } 
     //Stuff .... 
    } 

其他地方的软件

public void InitializeApp() { 
     //Stuff .... 
     MyApp.ViewForm.Add(new MySecondForm); 

     //Stuff .... 

} 

则命令为建立这样的。

public class CreateSecondForm : ICommand 
    { 
     myApp theApp; 
     public CreateSecondForm(myApp thisApp) { 
      theApp = thisApp; 
     } 

     public void Execute() { 
      SecondForm newform = theApp.Find(ViewFormEnum.SecondForm); 
      if (newForm != null) 
       newform.Load(); // Load the form and raise the events on its presenter. 
     } 

    } 

请原谅我的C#它不是我的主要语言。这种方法的优点是,包含表单的程序集可以用不同的表单集换出不同的程序集。这对于自动化测试而言,尤其适用于可以制作模拟类而不是表单的测试。您还可以将其设置为处理空视图,这对于释放完整应用程序的子集很有用。

尽管我强烈建议您使用该命令来包装视图的创建。根据应用程序,注册View的第二个建议可能会过度。在我的CAD/CAM应用程序中,我有几十个对话框和几个不同的主要形式,用于设置和控制2D金属切割台的不同方面。然而,在我公司的其他一些应用程序中,我使用了一种简单的方法,因为它们大多是简单的实用程序。