【问题标题】:Mvp View knows ModelMvp View 知道 Model
【发布时间】:2012-10-22 16:49:32
【问题描述】:

我正在尝试使用 MVP,但我注意到我的视图必须知道模型,我认为这在 MVP 中不应该发生。

这是一个例子:

public partial class TestForm : Form, ITestView
{
    public void LoadList(IEnumerable<AppSignature> data)
    {
        testPresenterBindingSource.DataSource = data;
    }
}

public interface ITestView
{
    event EventHandler<EventArgs> Load;
    void LoadList(IEnumerable<AppSignature> data);
}

public class TestPresenter
{
   private ITestView view;

   public TestPresenter(ITestView view)
   {  
       this.view = view;
       view.Load += View_Load;
   } 

   private void View_Load(object sender, EventArgs e)
   {
       var data = // get from model
       view.LoadList(data);
   }
}

问题是在 TestForm 中我需要参考 AppSignature。 在我看到的所有教程中,有一些简单的例子,比如 public void LoadList(IEnumerable&lt;String&gt; data) 无需参考模型。但是,即 DataGridView 如何发布当前行数据?

【问题讨论】:

    标签: c# .net winforms design-patterns mvp


    【解决方案1】:

    您的表单是视图,而不是演示者。因此它应该实现接口ITestView

    public interface ITestView
    {
        event EventHandler Load;
        void LoadList(IEnumerable<AppSignatureDto> data);
    }
    

    您的 Presenter 是订阅视图事件并使用视图属性来读取和更新视图的人:

    public class TestPresenter
    {
       private ITestView view;
    
       public TestPresenter(ITestView view)
       {  
           this.view = view;
           view.Load += View_Load;
       } 
    
       private void View_Load(object sender, EventArgs e)
       {
           List<AppSignature> signatures = // get from model
           List<AppSignatureDto> signatureDtos = // map domain class to dto
           view.LoadList(signatureDtos);
       }
    }
    

    正如我已经说过的,你的表单是一个视图,它对演示者和模型一无所知:

    public partial class TestForm : Form, ITestView
    {
        public event EventHandler Load;    
    
        private void ButtonLoad_Click(object sender, EventArgs e)
        {
            if (Load != null)
                Load(this, EventArgs.Empty);
        }
    
        public void LoadList(IEnumerable<AppSignatureDto> data)
        {
            // populate grid view here
        }
    } 
    

    如何处理对域类的引用?通常我只提供查看简单数据(字符串、整数、日期等),或者我创建传递给视图的数据传输对象(您可以将它们命名为 FooView、FooDto 等)。您可以使用 AtoMapper 之类的内容轻松映射它们:

    List<AppSignatureDto> signatureDtos = 
          Mapper.Map<List<AppSignature>, List<AppSignatureDto>>(signatures);
    

    【讨论】:

    • 你是对的。正如你所指出的,我已经改变了我的帖子,但我认为问题仍然存在。
    【解决方案2】:

    只要交互仅限于数据绑定,视图就可能知道模型。即视图不应尝试直接操作模型。 View 将始终将用户输入重定向到 Presenter,而 Presenter 将负责进一步的操作。如果 Presenter 执行的任何操作导致 Model 的状态发生变化,Model 将通过数据绑定通知 View。模型将完全不知道 View 的存在。

    【讨论】:

      【解决方案3】:

      可以在 Presenter 中获取 DataSource 并设置它的 DataSource 吗? 例如 演示者代码:

      Public void LoadData()
      {
          _view.Data.DataSource = Business.GetData().ToList();
      }
      

      表格代码:

      Public BindingSource Data
      {
          get
          {
              return this.bsData;
          }
      }
      

      感谢我不需要添加对视图的任何引用,但我没有在任何其他来源中看到该解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-10
        • 2018-08-03
        • 2014-04-29
        • 2012-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多