j'ai mis en place une triade MVP en utilisant le modèle de vue passif - à savoir la vue ne contient que des accesseurs simples et setters. Cependant, j'ai de la difficulté à séparer les données de vue et les données de modèle. En particulier lors de la manipulation d'un changement dans l'état d'affichage.MVP passif View - afficher les données de maintien et les données de modèle distinct
La triade est utilisée pour permettre à l'utilisateur de sélectionner une partie d'une liste. La liste des pièces est fournie par le modèle avec chaque partie identifiée de façon unique par un identifiant unique.
permet de dire que les parties ressemblent à ceci:
class Part
{
int ID; // this code uniquely identifies the part within the model
String partCode;
String description;
double voltage;
}
La vue affiche la liste à l'utilisateur et leur permet de sélectionner une partie
La liste est affichée dans une DataGridView et une partie est sélectionnée en cliquant sur une ligne dans le dataGridView.
L'ID est de ne pas être affiché à l'utilisateur et n'est la tension, donc le modèle crée un DataTable qui contient juste la partCode et la description. Ce DataTable est affecté par le présentateur à une propriété de la vue qui correspond à la propriété DataSource de DataGridView.
class Presenter
{
IView _view;
IModel _model;
//...///
_view.Data = _model.GetFilteredData();
}
class Model
{
public DataTable GetFilteredData()
{
// create a DataTable with the partCode and Description columns only
// return DataTable
}
}
class View //winform
{
public DataTable Data
{
set
{
this.dataGridView.Source = value;
}
}
}
Jusqu'ici tout va bien. La vue affiche les données filtrées dans DataGridView.
Le problème que j'ai est de retourner la partie sélectionnée par l'utilisateur.
La vue n'a aucune connaissance de l'ID unique car elle n'est pas affichée et les autres informations ne peuvent pas être garanties comme étant uniques - il n'est donc pas possible d'identifier de manière unique la pièce sélectionnée.
Essentiellement, je suis en train de convertir des données d'affichage (la ligne sélectionnée) pour modéliser des données (la partie sélectionnée) sans un composant en utilisant les données des autres.
Jusqu'à présent, j'ai les solutions suivantes:
1) La vue est passé avec succès un DataTable qui contient l'ID et filtre alors l'affichage pour qu'il ne soit pas affiché à l'utilisateur. Il est alors trivial de retourner un identifiant pour la ligne sélectionnée. Le problème ici est que j'ai maintenant pollué la vue avec une logique qui n'a pas été testée (le filtrage de l'affichage).
2) L'affichage retourne l'index de ligne et le modèle correspond à l'indice d'une ligne dans les données d'origine. Cela signifierait que l'ordre dans la vue ne change jamais, ce qui, dans la mesure du possible, restreint la façon dont la vue peut montrer (et manipuler) les données. Cela pollue également le modèle avec des données d'affichage (l'index de ligne).
public int RowIndexSelected { get; private set; }
//...//
private void gridParts_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (SelectedPartChangedEvent != null)
{
RowIndexSelected = e.RowIndex;
SelectedPartChangedEvent();
}
}
3) Une variation sur (2). Créez un objet adaptateur pour s'asseoir entre le présentateur et la vue. Déplacez la ligne vers le code de conversion d'ID du modèle à l'adaptateur. Le présentateur gère ensuite l'événement modifié par la partie dataGridAdapters.
public PartSelectDataGridAdapter(IPartSelectView view, PartCollection data)
{
_view = view;
_data = data;
_view.SelectedPanelChangedEvent += HandleSelectedPartChanged;
}
void HandleSelectedPartChanged()
{
int id = _data[_view.RowIndexSelected].ID;
if (SelectedPartChanged != null)
{
SelectedPartChanged(id);
}
}
À l'heure actuelle im apprentissage vers 3 car il est testable, maintient la logique à partir des données de vue et vue sur le modèle et le présentateur.
Comment aborderiez-vous cela - y a-t-il une meilleure solution?
Je devrais ajouter que j'ai suivi la méthodologie Presenter First décrite ici http://www.atomicobject.com/pages/Presenter+First. – Kildareflare