3

我正在尝试在我的应用程序中实现 Model-View-Presenter 设计模式。MVP 模式的一般概念对我来说是众所周知的,但我更难以使用嵌套的用户控件来完成它。

我有一些可能的方案我可以实现,但在这样做之前,我想听听你的意见。

我认为发布我的任何代码都没有关系,因为它更像是我试图理解的“概念”。

所以场景是:

1 个页面用于连接 2 个用户控件。这些用户控件之一包含一个子用户控件。在这种情况下,我如何使用 MVP 模式?

1 Page
  1 UC
  1 UC
     1 SubUC

编辑:

所以基本上我想知道的是我们如何在两个用户控件中使用 MVP 在两个视图(父视图和子视图)之间进行交互。

我将在没有 MVP 的 ASP.net 中向您展示一个示例:http: //pastie.org/5452134

现在有了 MVP,我们是否仍然使用 CodeBehind 注册这种事件?知道这个父用户控件和子用户控件都将使用 MVP 模式。或者演示者是否包含在此交互中?

最终我可以将代码更改为: http: //pastie.org/5452180

但我想知道这是否可行,考虑到 MVP 模式......

还是我们更需要这样的方法:http: //pastie.org/5452174

上面所有的例子都写在父视图的CodeBehind中。这是正确的吗?如果没有,我们如何使用更好的方法来实现这一点

编辑 2:我在示例方法中添加了一个解决方案:https ://github.com/frederikprijck/ASP.NET-MVP 我认为这应该是我想要的...

4

1 回答 1

5

我没有看到问题 - 用户控件只不过是一个视图。演示者可以一次与多个视图进行交互。因此,在这种情况下,您的演示者可以参考 4 个视图(一个用于页面,两个用于用户控件,最后一个用于子用户控件)。

或者,您希望每个演示者有一个视图,在这种情况下,您可以将用户控件视为父视图(页面)的子视图,因此父视图需要为演示者上下冒泡视图交互。但是,我更喜欢演示者处理交互多个视图的早期方法。

请参阅有关如何完成布线的相关问题:https ://softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts

最后,您可能想看看 MVVM 模式,我认为它非常适合组合 UI。您将拥有控制视图和模型之间交互的视图模型,而不是演示者 - 但是,与演示者不同,视图模型不知道视图 - 而是视图观察(和更新)视图模型以呈现自身。在这里看到这篇文章(视图模型被称为演示模型): http: //www.codeproject.com/Articles/23340/Presentation-Model-in-Action

编辑

老实说,我不喜欢你的任何方法。我喜欢 MVP 实现,其中演示者通过接口(无紧密耦合)持有对视图的引用,并且视图进行接线,即创建演示者实例并注入视图引用。演示者侦听视图事件并调用视图上的方法。View 从不直接调用演示者的方法。(MVP 的其他变体是可能的 - 请参阅我寻求的 SO 答案)。有了这个,我将解释我之前解释过的两种方法。

方法1

每个用户控件都是一个独立的视图。将有一个共同的演示者来处理多个视图。例如,

public class Presenter1
{
    IView1 _view1;
    IView2 _view2;

    public Presenter1(IView1 view1, IView2 view2)
    {
        _view1 = view1;
        _view2 = view2;

        _view1.OnSave += OnSave;
        _view1.OnSomeEvent += OnSomeEvent;
        _view2.OnFoo += OnFoo;
    }

    public void OnSave()
    {
        var data1 = _view1.GetData();
        var data2 = _view2.GetData();
        // update model
        ...
    }

    public void OnSomeEvent()
    {
       // inform view2 about it
       _view2.DoOnSomeEvent();
    }

    ...
}

public partial class MyPage : Page, IView1
{
   public void Page_Load(...)
   {
     //do wire up
     _presenter = new Presenter(this, usercontrol1);
   }
   ...
}

基本思想是视图不做串扰。如果用户控件需要通知页面某些事情,它会引发一个被演示者捕获的事件并将其通知页面。视图是被动的并处理 UI。

方法二:

用户控件和页面交互。在这种情况下,Page 将充当最终视图,Presenter 将对其进行引用。控件的事件将由页面处理,如有必要,页面将冒泡事件。例如,

IView1 : IView2 { }

public class Presenter1
{
   IView1 _view1;

   public Presenter1(IView1 view1)
   {
       _view1 = view1;

       _view1.OnSave += OnSave;
       _view1.OnSomeEvent += OnSomeEvent;
       _view1.OnFoo += OnFoo;
   }
   ...
}

public partial class MyPage : Page, IView1
{
       public void Page_Load(...)
       {
         //do wire up
         _presenter = new Presenter(this);

         // handle user control events
         UserControl1.Foo += UserControl1_OnFoo();
         UserControl1.XyzEvent += UserControl1_XyzEvent();

       }
       ...

       private void UserControl1_OnFoo(...)
       {
          // bubble up to presenter
          OnFoo(..)
       }

       private void UserControl1_XyzEvent(...)
       {
          // private interaction (purely about some UI manipulation), 
          // will not be bubble up to presenter
          ...
       }
}
于 2012-11-29T09:13:47.103 回答