【问题标题】:How to Bind Data and manipulate it in a GridView with MVP如何使用 MVP 在 GridView 中绑定数据并对其进行操作
【发布时间】:2010-03-04 18:20:12
【问题描述】:

我对整个 MVP 的事情还很陌生,并且慢慢地了解这一切。我遇到的一个问题是如何在填充 GridView(和 ddls,但我们稍后会解决)时与 MVP 方法保持一致。

可以直接连接到 ObjectDataSourceID 吗?对我来说,这似乎是错误的,因为它绕过了 MVP 所做的所有关注点分离。

那么,话虽如此,我该怎么做呢?我如何处理排序(我是否将处理程序事件发送到表示层,如果是的话,它在代码中的外观如何)? 现在我有一个没有排序的 GridView。代码如下。

ListCustomers.aspx.cs:

public partial class ListCustomers : System.Web.UI.Page, IlistCustomer
{
protected void Page_Load(object sender, EventArgs e)
{
    //On every page load, create a new presenter object with
    //constructor  recieving the 

    //  page's IlistCustomer view 
    ListUserPresenter ListUser_P = new ListUserPresenter(this);

    //Call the presenter's PopulateList to bind data to gridview
    ListUser_P.PopulateList();

}

GridView IlistCustomer.UserGridView
{
    get { return gvUsers; }
    set { gvUsers = value; }
}

}

接口 (IlistCustomer.cs):这是在整个 Gridview 控件中发送的错误吗?

public interface IlistCustomer
{
GridView UserGridView { set; get; }
}

演示者 (ListUserPresenter.cs):

public class ListUserPresenter
{
private IlistCustomer view_listCustomer;
private GridView gvListCustomers;
private DataTable objDT;

public ListUserPresenter( IlistCustomer view)
{
    //Handle an error if an Ilistcustomer was not sent in)
    if (view == null)
        throw new ArgumentNullException("ListCustomer View cannot be blank");

    //Set local IlistCustomer interface view
    this.view_listCustomer = view;
}

public void PopulateList()
{
    //Fill local Gridview with local IlistCustomer
    gvListCustomers = view_listCustomer.UserGridView;

    // Instantiate a new CustomerBusiness object to contact database
    CustomerBusiness CustomerBiz = new CustomerBusiness();

    //Call CustomerBusiness's GetListCustomers to fill DataTable object
    objDT = CustomerBiz.GetListCustomers();

    //Bind DataTable to gridview;
    gvListCustomers.DataSource = objDT;
    gvListCustomers.DataBind();
}
}

【问题讨论】:

    标签: asp.net mvp


    【解决方案1】:

    我将首先强调 MVP 作为模式解决的主要问题。首先是通过关注点分离来实现模块化。这意味着可以理想地将 View 层从 Web 窗体更改为 Windows 窗体,而无需更改 Presenter 和 Model 层中的任何内容。其次,使用 MVP 设计的应用程序很容易进行单元测试,因为测试表单非常困难。考虑到这一点,您就会意识到不应在 Presenter 层中操作像 Grid 这样的以视图为中心的对象,因为当视图发生变化时,控件也可能发生变化。为了回答您的问题,我可以通过以下方式解决您的问题:

    // View
    public interface IListCustomersView
    {
        public void BindGrid(IList<Customer> customers);
    }
    
    // Form e.g. Web Form, Windows Form
    public class ListCustomers : IListCustomersView
    {
        private ListCustomersPresenter listCustomerPresenter = null;
    
        public ListCustomers()
        {
            // You can use a Dependency Injector here
            this.listCustomersPresenter = new ListCustomerPresenter(
                new CustomerRepository(),
                this);
        }
    
        public void BindGrid(IList<Customer> customers)
        {
                grid.DataSource = customers;
                grid.Databind();
        }
    }
    
    // Presenter
    public class ListCustomersPresenter
    {
        private readonly IListCustomersView view = null;
        private readonly ICustomerRespository repository = null;
    
        public ListCustomersPresenter(
             ICustomerRespository  customerRepository, IListCustomersView view)
        {
            Guard.AgainstNull(view,"View");
            Guard.AgainstNull(customerRepository,"CustomerRepository");
    
            this.view = view;
            this.customerRepository = customerRepository;
        }
    
        public void BindGrid()
        {
             // Fetch customers from repository
             IList<Customer> customers = this.customerRepository.GetCustomers();
             view.BindGrid(customers);          
        }
    }
    

    【讨论】:

      【解决方案2】:

      使用数据库感知控件(如 Gridview)的便利性是一个巨大的诱惑。理论上,人们可以滚动他们自己的 gridview 并保持对 MVP 设计的忠诚。但是您将重复工作,并为企业提供有限的资源,这通常不是最明智的选择。由于可以节省大量时间,因此有充分的理由使用数据库感知控件。

      折衷方案是通过代码清楚地记录控件连接到数据库的路径。这样,当您迁移 UI、后端或两者时,您可以看到依赖于数据库感知控件和后端的内容。还要查看您的框架提供的数据库 API。您可能有一个接近通用的选择,可以最大限度地减少更改后端的问题。

      在规划您的设计时,要问的关键问题是“如果我更改 UI、演示器、视图、模型或数据库后端会发生什么。希望答案将引导您进行允许更改的设计。

      【讨论】:

      • 啊,所以可能不想使用gridviews吧?我将在我正在寻找的设计中对实现此目的的最佳方法进行更多研究。感谢您为我提供了一条新的研究途径。
      • 当然,但请记住,gridview 可以节省大量时间,因此也可以考虑这一点。只要数据库与gridview之间的连接是明确的文档,您就可以在以后的版本中使用。
      【解决方案3】:

      视图界面不应暴露 UI 组件;我的看法如下

      public interface IlistCustomer
      {
         PopulateCustomers(IEnumerable<Customer> customers);
      }
      
      public class ListUserPresenter
      {
      private IlistCustomer _view;
      
      public ListUserPresenter(IlistCustomer view)
      {
          //Handle an error if an Ilistcustomer was not sent in)
          if (view == null)
              throw new ArgumentNullException("view");    
      
          _view = view;
      }
      
      public void PopulateList()
      {
         //Injecting your DAL seems like a good choice here
          CustomerBusiness CustomerBiz = new CustomerBusiness();    
      
          IEnumerable<Customer> customers = CustomerBiz.GetListCustomers();
      
          _view.PopulateCustomers(customers);
      }
      }
      

      【讨论】:

      • 你说的很对乐宇。当我这样做时,我意识到这是错误的,但作为一个完整的网络表单人,我当时找不到任何其他方法。我认为我知道视图中应该包含的内容是错误的。我认为它不应该做任何事情,除了提供由演示者填写的项目。现在我明白视图应该比我想象的要多。感谢乐宇的投入。这很有帮助。
      猜你喜欢
      • 2012-04-26
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-16
      相关资源
      最近更新 更多