2010-03-04 11 views
3

Je suis novice en matière de MVP et je me mets lentement à l'œuvre. Le problème que je rencontre est de savoir comment rester cohérent avec la méthodologie MVP lors du remplissage de GridViews (et ddls, mais nous y reviendrons plus tard).Comment lier des données et le manipuler dans un GridView avec MVP

Est-il acceptable de le connecter directement à un ObjectDataSourceID? Pour moi, cela semble faux, car il contourne toute la séparation des préoccupations MVP a été fait pour faire.

Donc, avec cela dit, comment puis-je le faire? Comment gérer le tri (est-ce que j'envoie des événements de gestionnaire à la couche de présentation, si oui, à quoi cela ressemble-t-il dans le code)? En ce moment j'ai un GridView qui n'a pas de tri. Code ci-dessous.

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

} 

Interface (IlistCustomer.cs): est-ce mauvais envoi dans un contrôle GridView entier?

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

Le présentateur (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(); 
} 
} 

Répondre

1

La commodité d'utiliser une base de données de contrôle conscient, comme Gridview, tentation est grande. En théorie, on pourrait simplement rouler leur propre gridview et rester fidèle à la conception MVP. Mais vous allez dupliquer le travail et donner les ressources limitées des entreprises pas souvent le choix le plus judicieux. Étant donné que le gain de temps peut être considérable, il existe des raisons impérieuses d'utiliser des contrôles sensibles à la base de données.

Le compromis est de documenter clairement par code le chemin dans lequel le contrôle se connecte à la base de données. De cette façon, si et quand vous migrez l'interface utilisateur, le backend ou les deux, vous pouvez voir ce qui dépend du contrôle conscient de la base de données et du backend. Jetez aussi un coup d'œil sur les API de base de données offertes par votre framework. Vous avez peut-être un choix générique qui minimise le problème de changement de backend. Lorsque vous planifiez votre conception, la question clé à se poser est la suivante: «Que se passe-t-il si je modifie l'interface utilisateur, le présentateur, la vue, le modèle ou le backend de la base de données.

+0

Ah, Donc, vous ne voulez probablement pas utiliser gridviews hein? Je vais faire d'autres recherches sur la meilleure façon de faire cela dans le design que je cherche. Merci de m'avoir donné un nouveau chemin à la recherche. – DotNetDan

+0

Bien sûr, mais rappelez-vous que le gridview peut être un énorme gain de temps, donc aussi bien. Tant que la connexion entre la base de données et le gridview est clairement documentée, vous devriez être d'accord pour les futures versions. –

1

l'interface de vue ne doit pas exposer les composants de l'interface utilisateur, mon opinion serait la suivante

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); 
} 
} 
+0

Vous êtes très correct Leyu.Je me suis rendu compte que c'était faux quand je le faisais, mais je ne pouvais pas trouver d'autre moyen à ce moment-là d'être un gars plein de formulaires Web. Ce que je pensais savoir sur ce qui devrait être dans la vue était faux. Je pensais que cela ne devrait rien faire d'autre que donner des éléments à remplir par le présentateur. Maintenant, je comprends que la vue devrait faire plus que je ne le pensais. Merci Leyu pour votre contribution. C'était utile. – DotNetDan

3

Je commencerai par souligner les principales préoccupations soulevées par le MVP comme modèle Tout d'abord, il est de parvenir à la modularité grâce à la séparation des. Cela signifie que l'on peut idéalement changer le calque View des formulaires Web par exemple aux formulaires Windows sans chnagi n'importe quoi dans les couches Presenter et Model. Deuxièmement, une application conçue en utilisant MVP se prête facilement aux tests unitaires car il est très difficile de tester un formulaire. En gardant cela à l'esprit, vous réalisez que les objets centrés sur la vue comme Grid ne doivent pas être manipulés dans la couche Presenter car, lorsque la vue change, les contrôles sont susceptibles de changer. Pour répondre à votre question, je peux aborder votre problème de la façon suivante:

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