Mvp View知道模型

时间:2012-10-22 16:49:33

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

我正在尝试使用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<String> data),无需参考模型。但DataGridView如何发布当前行数据呢?

3 个答案:

答案 0 :(得分:2)

您的表单是一个视图,它不是演示者。因此,它应该实现接口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);

答案 1 :(得分:2)

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

答案 2 :(得分:0)

在Presenter中获取DataSource并设置其DataSource是否可以? 例如 演示者代码:

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

表格代码:

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

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