如何在带有MVP的GridView中绑定数据并对其进行操作

时间:2010-03-04 18:20:13

标签: asp.net mvp

我是整个MVP的新手,慢慢地让我全神贯注。我遇到的一个问题是如何在填充GridViews时使用MVP方法(和ddls,但我们稍后会解决这个问题)。

将它直接连接到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; }
}

Presenter(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();
}
}

3 个答案:

答案 0 :(得分:3)

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

// 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);          
    }
}

答案 1 :(得分:1)

使用数据库感知控件(如Gridview)的便利性是一个巨大的诱惑。从理论上讲,人们可以推出自己的网格视图并坚持MVP设计。但是,你将重复工作,并提供有限的业务资源,而这往往是最明智的选择。由于节省时间可能相当大,因此有充分的理由使用数据库感知控件。

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

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

答案 2 :(得分:1)

视图界面不应公开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);
}
}